Comments on parts of a web page

By Tom on 14-02-2007 11:00

Idea

Letting users place comment on an article of a website is nothing new. In the current age of Web 2.0, it is almost mandatory to give the visitors of your website a means to express their thoughts on what you publish on your site.

While browsing the Internet, on my quest for new mental nourishment, I came across the site of Jack Slocum, a YUI wizard (Yahoo! UI library). Instead of the regular system, where visitors put comments underneath the article, he presented them with the possibility to comment each line of his blog.

Instead of having to quote the piece of text you’re referring to, you can just place a comment next to it. Great idea. Like Borat would say: I like!

That’s why I decided to build a similar system. Here’s a link to the demo: http://www.encapsulated.org/tests/comments.htm



Functionality

On Jack Slocum’s blog, you can place a comment next to each line of text. You do so by clicking left of the line, and then a popup appears where you can enter your comment.

My system will be slightly different because I’m a bit lazy. Instead of allowing comments on each line, I only allow comments on blocks of HTML: paragraphs, pieces of code, titles, tables, lists,…

Also, instead of clicking left of the block of HTML, you simply double click on the text of the block. Then, a popup will appear.



Conditions

Minimize additional server-side code

Since I already have a working commenting system on my website, I don’t feel like writing a whole new set of PHP pages to process the input of this new commenting system. That’s why I will only allow a very minimum of new PHP code to be written. If you want to make use of (parts of) my code, you won’t have to change much to your existing code.


Unobtrusive Javascript

The biggest part of this new system will be written in Javascript. Since I’m really in favor of functionality for every visitor, the new code has to be degradable, unobtrusive… When you don’t have Javascript turned on, you should just receive the old commenting system, which works without Javascript enabled.


Approaching Jack Slocum’s system

I like how he worked with these fade in and fade out effects when a new window appears on your screen. These effects are not mandatory to create such a system, but it will be nicer for the eye. For this, I will make use of the Prototype library, in combination with Script.aculo.us.


Layout independency

The code has to be sturdy. If you make a new template for your site, with different colours, then the comments have to adjust automatically. This can be accomplished by reading all relevant CSS from the page, without hard-coding any colours.



Modifications to the original code

Identifying each block

The biggest nut to crack was how to identify each block of HTML, without making modifications to the original published text. If a visitor makes a comment on a certain paragraph, then the system has to be able to display this comment on the correct spot for all subsequent visits. Modifying the published text could lead to abuse (or extensive testing), so I don’t want to allow that.

After thinking very hard, I came with a solution: using the MD5 hash of the block as an identifier. This is how it works:

hashing scheme

Creating an MD5 hash for an HTML block

MD5 hashes have a very low probability of collision. The chance that 1 page of my site will contain two identical MD5 hashes for 2 different blocks of HTML is incredibly small. Hence I think this is a good system to identify each HTML block, without having to modify the original HTML.

There is a drawback though. If a certain block has any comments, and you decide to change something in that block, then the MD5 hash will change. The old comments won’t be seen anymore after you updated your page, because their associated MD5 hash won’t be found anymore.


Changes in the database

The comments are stored in a database. The only update there is an extra field “mdid” to store the MD5 of the HTML block the comment reffers to. In my database design, I have also a field with the page name of my blog post. In my Javascript code, I make use of this page name. The combination of the page name and the MD5 is a good identifier for a comment on a specific block of HTML on a specific page.


Changes in the PHP code

To process the submitted comment, I call the page “postcomment.php”. There I made some changes so this page also stores the MD5 hash (mdid) in the database. If no mdid is given to the page, I assume the comment wasn’t posted via the new system, but via the old form. This is a good way to check what output I should give. I won’t give the entire code for “postcomment.php”, just some relevant parts.

Getting the mdid:

$cmdid = "";
if (isSet($_POST["mdid"]))
	$cmdid = $_POST["mdid"];

Saving it to the database (makes use of PEAR DB abstraction):

$query = "INSERT INTO " . CONFIG_tableprefix . "comments (`postid`,`creation`,`name`,`email`,`homepage`,`title`,`content`,`spam`,`mdid`) VALUES (?,?,?,?,?,?,?,?,?)";
$qvals = Array($cpostid,date("YmdHi"),$cname,$cemail,$chomepage,$ctitle,$ccontent,0,$cmdid);
$qprep = $conn->prepare($query);
$conn->execute($qprep,$qvals);

Make a distinction between regular output, and output for the AJAX calls in the Javascript:

if ($cmdid == "")
	header("Location: http://www.encapsulated.org/post/" . $urlname);
else
	die("");


Writing the code

Part 1: Loading the existing comments

Load all hashes for a page

After the page has loaded, the Javascript we’re about to write, should kick in. The first thing it should do, is load all the blocks with comments attached into an array. For this, we need to query the database, so logically we’ll have to make use of AJAX to accomplish this.

I always write an init() function. When the page is loaded, this is the first function that’s being called. Everything else starts from init().

I also try to use the singleton notation as much as possible. This means that all functionality is stored into one single Javascript variable. The advantage of this is encapsulation: all data and functions are encapsulated into one namespace, so it won’t interfere with already existing Javascript.

Here’s how the first lines look like:

var Comments = {
	init:function(){
	}
}

Init() still is empty. We’ll fill it up. Remember we’re using already existing functionality. My already existing comment form is placed inside a DIV, with id “commentform”. The already existing comments are in a DIV with id “commentlist”. So firstly we need to hide these two DIV’s from the public’s eye.

Secondly, we will load all the MD5 hashes of this page. For this we create a new function load(), and we call it in init().

Lastly, we attach an eventlistener to the body of this HTML page. The eventlistener listens for a doubleclick event on the page. When a doubleclick is detected, we show the commentform.

Code:

init:function(){
	// hide regular comments & form
	$("commentlist").hide();
	$("commentform").hide();
				
	// load all comments:
	Comments.Load();

	// attach doubleclick event:
	Comments.addEvent(document,"dblclick",Comments.detectElement);
}

The load() function will make an XMLHTTPRequest to a PHP page that will return a list of all the MD5 hashes with associated comments for this page. We save these hashes in the array comel. For this, we pass the name of the current page to the PHP page.

Load:function(){
	// 1. load MD5's of all commented blocks on this page
	var url = window.location.toString();
	url = url.split("/").last().split("#").first().split("?").first();
	new Ajax.Request("ajax_commentmds.php",{postBody:"post=" + url,onComplete:function(req){
		Comments.comel = eval('([' + req.responseText + '])');
						
		// 2. travel the DOM, and attach markers where there are comments
		Comments.travelNodes(document.documentElement.lastChild);
	}});
}

Ajax.Request, last(), first() and $ are Prototype functionality. Other Prototype functionality will be used throughout this script. I will notify you every first time I use a function from Prototype.

The code for ajax_commentmds.php looks like this:

<?php
	// configuration info
	include("config.inc.php");
	
	if (isSet($_POST["post"]))
	{
		$page = $_POST["post"];
		
		// Performing SQL query
		$query = "SELECT id FROM " . CONFIG_tableprefix . "posts WHERE urlname='" . $page . "'";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$line=mysql_fetch_array($result,MYSQL_ASSOC);
		$postid = $line["id"];
		
		$query = "SELECT DISTINCT(mdid) AS mdid FROM " . CONFIG_tableprefix . "comments WHERE postid=$postid";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$mdids = "";
		while($line=mysql_fetch_array($result,MYSQL_ASSOC))
		{
			if ($mdids == "")
				$mdids = "\"" . $line["mdid"] . "\"";
			else
				$mdids .= ",\"" . $line["mdid"] . "\"";
		}
		die($mdids);
	}
?>

What this code does, is selecting all the different MD5 hashes that are in the database for this specific page. Each MD5 hash represents a block of HTML code. It’s up to the Javascript to check which MD5 hash belongs to which block of HTML.

In case you’re wondering about my config file. Here is a censored version.

<?php
	/* DATABASE */
	$db_hostname = "localhost";
	$db_user = "*********";
	$db_pwd = "*********";
	$db_database = "********";
	// Connecting, selecting database
	$link = mysql_connect($db_hostname, $db_user, $db_pwd)
	   or die('Could not connect: ' . mysql_error());
	mysql_select_db($db_database) or die('Could not select database');

	@define("CONFIG_sitename","Encapsulated.org");
	@define("CONFIG_tableprefix","enc_");
?>

Search corresponding parts of the page

We now have an array with all the MD5 hashes of this page. We now need to check the DOM to know where a comment was made. For this, I made a recursive function that travels each node of the DOM, and checks if its inner HTML corresponds to an MD5 hash in our array. If so, we know that a comment was made on that specific block of HTML. In Javascript, this results to the following code:

travelNodes:function(el){
	if (el.innerHTML)
	{
		var elMD5 = MD5(el.innerHTML);
		if (Comments.comel.indexOf(elMD5) >= 0)
		{
			// use AJAX to find out the amount of comments for this MD5 marker:
			var url = window.location.toString();
			url = url.split("/").last().split("#").first().split("?").first();
			new Ajax.Request("ajax_commentcount.php",{postBody:"md=" + elMD5 + "&post=" + url,onComplete:function(req){
				Comments.createMarker(elMD5,el,req.responseText);
			}});
		}
		if (el.childNodes.length > 0)
		{
			for (var i=0;i<el.childNodes.length;i++)
			{
				Comments.travelNodes(el.childNodes[i]);
			}
		}
	}
}

travelNodes() receives a DOM element as input. The first time, we input the “body” tag, because all other elements can be found by recursively traveling the DOM from that point.

The first thing we do, is take the MD5 hash of that element’s inner HTML. A Javascript implementation of MD5 can be found on http://pajhome.org.uk/crypt/md5/md5src.html. Then we check if that MD5 is in our array of all the hashes. The function indexOf() is part of the Prototype library.

If the MD5 is found in the array, we use AJAX to find out how many comments were made on that block of HTML. And then we insert a marker with the function createMarker(). More about this function later on.

Then for each child of the current element, we need to travel it’s DOM to find more comments. This is the recursive part of the function. It calls itself.

Insert a comment marker

A comment marker looks like this: comment marker

I have placed it left of the block of HTML it’s associated with. The “2” indicates the amount of comments on this particular block of HTML. For simplicity, I just made an image that represents a speech bubble. It is however possible to make this entirely with Javascript and CSS, using Curvy Corners.

Previously, we made an AJAX call to ajax_commentcount.php. This is the code for this page:

<?php
	// configuration info
	include("config.inc.php");
	
	if (isSet($_POST["md"]) && isSet($_POST["post"]))
	{
		$md = $_POST["md"];
		$page = $_POST["post"];
		
		// Performing SQL query
		$query = "SELECT id FROM " . CONFIG_tableprefix . "posts WHERE urlname='" . $page . "'";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$line=mysql_fetch_array($result,MYSQL_ASSOC);
		$postid = $line["id"];
		
		$query = "SELECT COUNT(*) AS amount FROM " . CONFIG_tableprefix . "comments WHERE postid=$postid AND mdid='" . $md . "'";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$line=mysql_fetch_array($result,MYSQL_ASSOC);
		die($line["amount"]);
	}
?>

It simply returns a number: the amount of comments for a specific page and specific MD5 hash.

The Javascript function to insert the marker on the page, needs to know 3 things: the MD5 hash of that block, the specific element in the DOM where the comment belongs to, and the amount of comments.

createMarker:function(diggest,par,amount){
	var newel = document.createElement("span");
	var elPos = Position.cumulativeOffset(par);
	newel.style.cssText = "position:absolute;top:" + (elPos[1]-5) + "px;left:" + (Element.getStyle($("main"),"margin-left").replace("px","")*1-20) + "px;font-size:10px;font-family:Verdana;font-weight:normal;text-decoration:none;background:url('../templates/theme1/images/cbal.gif') no-repeat left center;padding:3px 3px 3px 5px;cursor:pointer;width:25px;";
	newel.innerHTML = amount;
	newel.setAttribute("id",diggest);
	newel.className = "comtag";
	Comments.addEvent(newel,"click",Comments.showComments);
	document.documentElement.lastChild.appendChild(newel);
}

What we do is:

This is how I’ve done it to position the marker. For me it was the easiest way, because I’m already used to Prototype.

So far, we can already load all comments from the database, and insert a marker at the appropriate block of HTML. The next step is to show the corresponding comments when you click a marker.


Displaying comments

Showing comments

showComments:function(){
	var mdid = this.getAttribute("id");
	
	// if the comment form is displayed for this block, hide it first:
	var f = document.forms["addcomment"];
	if (typeof f.elements["mdid"] != "undefined")
	{
		if($("addcomment"))
		{
			if (f.elements["mdid"].value == mdid && Element.getStyle($("addcomment"),"opacity")*1 > 0)
				Comments.hideDiv((Element.getStyle($(mdid),"left").replace("px","")*1),'addcomment');
		}
	}
	
	var url = window.location.toString();
	url = url.split("/").last().split("#").first().split("?").first();
	var div;
	if (!$("showcomment"))
		div = document.createElement("div");
	else
		div = $("showcomment");
	
	div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle($(mdid),"top") + ";left:" + Element.getStyle($(mdid),"left") + ";display:block;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;overflow:auto;";
	
	new Ajax.Request("ajax_commentdisplay.php",{postBody:"mdid=" + mdid + "&page=" + url,onComplete:function(req){
		div.innerHTML = "<img src=\"../templates/theme1/images/btnClose.gif\" border=\"0\" title=\"close\" style=\"float:right;clear:both;margin-right:10px;cursor:pointer;\" onclick=\"Comments.hideDiv(" + (Element.getStyle($(mdid),"left").replace("px","")*1) + ",'showcomment');\" />" + req.responseText;
		if (!$("showcomment"))
		{
			document.documentElement.lastChild.appendChild(div);
			div.setAttribute("id","showcomment");
		}
		//Comments.displayComments($(mdid));
		Comments.displayDiv($(mdid),'showcomment');
	}});
}

This function creates a DIV element, with all the comments for that particular block of HTML. We create the DIV only once, and re-use it when we want to display the comments for other blocks. In the style of the DIV, we set the opacity to 0. This way, the block is created, but not yet visible. We need this for the visual effects later on.

The AJAX call to ajax_commentdisplay.php receives all the comments that are associated with a given MD5 hash from the database:

<?php
	// configuration info
	include("config.inc.php");
	
	if (isSet($_POST["page"]) && isSet($_POST["mdid"]))
	{
		$page = $_POST["page"];
		$md = $_POST["mdid"];
		
		// Performing SQL query
		$query = "SELECT id FROM " . CONFIG_tableprefix . "posts WHERE urlname='" . $page . "'";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$line=mysql_fetch_array($result,MYSQL_ASSOC);
		$postid = $line["id"];
		
		$query = "SELECT * FROM " . CONFIG_tableprefix . "comments WHERE postid=$postid AND mdid='" . $md . "'";
		$result = mysql_query($query) or die('Query failed: ' . mysql_error());
		$output = "";
		$teller = 0;
		while($line=mysql_fetch_array($result,MYSQL_ASSOC))
		{
			$commentcolor = "1";
			if ($teller%2)
				$commentcolor = "2";
				$datum = $line["creation"];
				$datum = $datum[6] . $datum[7] . "-" . $datum[4] . $datum[5] . "-" . $datum[0] . $datum[1] . $datum[2] . $datum[3] . " " . $datum[8] . $datum[9] . ":" . $datum[10] . $datum[11];	
			$output .= 	"<div class=\"comment$commentcolor\"><h4>" . stripslashes($line["title"]) . "</h4>" . stripslashes($line["content"]) . "<p class=\"caption\">by " . stripslashes($line["name"]) . " on $datum</p></div>";
		}
		die($output);
	}
?>

 

example

example of how the displayed comments look like

When you hit the close button, the function hideDiv() will be called. Some effects will be applied to hide the comments. In the next section I’ll talk about the effects.

Adding effects

It is possible to simply hide and show the comments. But one of my goals was to mimic the effects of Jack Slocum’s system. For this, I am using the script.aculo.us library, which can be found on http://script.aculo.us.

The original behavior can be broken down to 3 basic steps in the script.aculo.us library:

All of them have to run in parallel, thus at the same time. With script.aculo.us, this can be accomplished like this:

displayDiv:function(marker,divid){
	var xmov = (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 4)-(Element.getStyle(marker,"left").replace("px","")*1);
	new Effect.Parallel(
		[ new Effect.MoveBy($(divid), 0, xmov,
			{ sync: true,transition:Effect.Transitions.slowstop }),
		  new Effect.Opacity($(divid), 
			{ sync: true, to: 0.9, from: 0.0 } ),
		new Effect.Scale($(divid), 1000, {sync:true,scaleContent:false,scaleMode: { originalHeight: 35, originalWidth: (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 20) }})],
		{ duration: 0.7,afterFinish:function(effect){
			// scroll to the div
			$(divid).scrollTo();
		}}
	  );
}

We first determine the amount of pixels that the comment DIV has to move (from the marker to a centered position on the screen).

Then, in parallel, we apply the effects. When they are finished, 0.7 seconds later, we let the page automatically scroll to the DIV, by using the Prototype function scrollTo().

I won’t explain the syntax for script.aculo.us here. If you need more information, you can always visit their site, and consult the wiki. Everything is explained thoroughly there.

To hide the comments, we simply use a reversed functionality. This function however, doesn’t need the marker element, but the “left” property of its CSS:

hideDiv:function(markerleft,divid){
	var xmov = 0-((Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 4)-markerleft);
	new Effect.Parallel(
		[ new Effect.MoveBy($(divid), 0, xmov,
			{ sync: true,transition:Effect.Transitions.slowstop }),
		  new Effect.Opacity($(divid), 
			{ sync: true, to: 0.0, from: 0.9 } ),
		new Effect.Scale($(divid), 0.001, {sync:true,scaleContent:false,scaleMode: { originalHeight: Element.getStyle($(divid),"height").replace("px","")*1, originalWidth: Element.getStyle($(divid),"width").replace("px","")*1 }})],
		{ duration: 0.7,afterFinish:function(effect){
			$(divid).hide();
		}}
	  );
}

We will re-use these effects for displaying and hiding the comment form.


Adding comments to the page

Display the comment form

The comment form should be shown whenever someone double clicks on a block of HTML. Either this block already has comments attached, or it is the first one we attach now. In init(), we already attached an event listener to the document. After a double click, the function detectElement() is executed:

detectElement:function(e){
	if (!e) var e = window.event;
	var targ;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	
	var blockElements = ["address","blockquote","center","code","div","dir","h1","h2","h3","h4","h5","h6","hr","pre","p","table","ol","ul","dl"]
	if (blockElements.indexOf(targ.nodeName.toLowerCase()) >= 0)
		Comments.detectComment(targ,targ);
	else
	{
		// if target = subelement of a blockElement => detect blockElement
		var targ2;
		var par = targ;
		while(targ = targ.parentNode)
		{
			if (blockElements.indexOf(targ.nodeName.toLowerCase()) >= 0)
			{
				targ2 = par;
				break;
			}
		}
		Comments.detectComment(targ,targ2);
	}
}

In the first part of the code, we try to detect which element the user clicked on. This piece of code was found on Quirksmode. I used it because it gives cross-browser code to detect the clicked element.

Next, I defined a list of block elements. Only block elements can contain comments. This is to make sure there are no in-line markers. If the clicked element (or target) is not a block element, we go back in the DOM tree, and try to find the containing block element.

Once we are sure we have a block element, the function detectComment() is called. Here, we check if the block of HTML already has comments or not:

detectComment:function(orig,par){
	if (typeof par != "undefined")
	{
		var elMD5 = MD5(par.innerHTML);
		if (!$(elMD5))
			Comments.createMarker(elMD5,par,0);
		Comments.insertComment($(elMD5));
	}
}

If it doesn’t, we first create a marker (explained in a previous section), and then we call insertComment() to show the comment form.

insertComment:function(marker){
	// check if the comment div is not displaying for this block:
	if($("showcomment"))
	{
		if (Element.getStyle(marker,"top") == Element.getStyle($("showcomment"),"top") && Element.getStyle($("showcomment"),"opacity")*1 > 0)
			Comments.hideDiv(Element.getStyle(marker,"left").replace("px","")*1,'showcomment');
	}
	
	if (!$("addcomment"))
	{
		var div = document.createElement("div");
		div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle(marker,"top") + ";left:" + Element.getStyle(marker,"left") + ";display:block;filter:alpha(opacity=10);-moz-opacity:.10;opacity:.10;overflow:hidden;";
		div.setAttribute("id","addcomment");
		// append a hidden input field with the MD5 of this marker
		var f = $("commentform").getElementsByTagName("form")[0];
		var h = document.createElement("input");
		h.setAttribute("type","hidden");
		h.setAttribute("name","mdid");
		h.setAttribute("value",marker.getAttribute("id"));
		f.appendChild(h);
		// catch the submission of the form:
		for(var i=0;i<f.elements.length;i++)
		{
			if (f.elements[i].name == "btnSubmit")
			{
				f.elements[i].setAttribute("type","button");
				f.elements[i].onclick = "Comments.catchSubmit();";
				f.elements[i].setAttribute("onclick","Comments.catchSubmit()");
			}
		}
		
		div.innerHTML = "<img src=\"../templates/theme1/images/btnClose.gif\" border=\"0\" title=\"close\" style=\"float:right;clear:both;margin-right:10px;cursor:pointer;\" onclick=\"Comments.hideDiv(" + (Element.getStyle(marker,"left").replace("px","")*1) + ",'addcomment');\" />" + $("commentform").innerHTML;
		
		// otherwise there's two times the comment form, and the invisible one gets submitted (it's the first one in the dom)
		$("commentform").parentNode.removeChild($("commentform"));
		
		document.documentElement.lastChild.appendChild(div);
		//Comments.displayCommentForm(marker);
		Comments.displayDiv(marker,'addcomment');
	}
	else
	{
		var div = $("addcomment");
		div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle(marker,"top") + ";left:" + Element.getStyle(marker,"left") + ";display:block;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;overflow:hidden;";
		// update the hidden field with the MD5
		var f = div.getElementsByTagName("form")[0]; // the form already exists, so we need to modify it
		f.elements["mdid"].value = marker.getAttribute("id");
		//Comments.displayCommentForm(marker);
		Comments.displayDiv(marker,'addcomment');
	}
}

On the page, we already had a comment form, but one of our first actions was to hide the form. We will now copy the entire form to a new div, and remove the old one. We need to add a hidden field that contains the MD5 hash of the commented HTML block. To achieve this, insertComment() does the following:

We make use of Prototype to correctly position the DIV, and assign the correct colors.

Catch form submission

When we click the button to submit the form, we the function catchSubmit() is triggered.

catchSubmit:function(){
	var f = document.forms["addcomment"];
	var Qstring = f.serialize();
	new Ajax.Request(f.getAttribute("action"),{postBody:Qstring,onComplete:function(req){
		if (req.responseText == "")
		{
			f.reset();
			// update the marker:
			var mdid = f.elements["mdid"].value;
			$(mdid).innerHTML = ($(mdid).innerHTML*1 + 1);
			
			// if this is the first comment of this block, then update the array with all MD5s:
			if (Comments.comel.indexOf(mdid) < 0)
				Comments.comel.push(mdid);
			
				Comments.hideDiv((Element.getStyle($(mdid),"left").replace("px","")*1),'addcomment');
		}
		else
		{
			if (req.responseText == "spam")
				location = "http://www.encapsulated.org/spam.php";
			else
				alert(req.responseText);
		}
	}});
}

Prototype has a handy function to create a correct query string from a form: form.serialize(). Now that we have the querystring, we submit it to our original PHP page to handle the form. This address is not hard coded in the function, but the function detects the correct URL from the original form.

After the comment is submitted, we add the new MD5 hash to our list in “comel”. Then we hide the form, using hideDiv(), and we increment the counter in our marker. I also added some extra code because my PHP page is able to detect spam. Well, in most cases it is.

Visual effects

We re-use the functions we implemented for showing and hiding the comments on a page.



Entire code

var Comments = {
	comel:Array(),
	init:function(){
		// hide regular comments & form
		$("commentlist").hide();
		$("commentform").hide();
		
		// load all comments:
		Comments.Load();

		// attach doubleclick event:
		Comments.addEvent(document,"dblclick",Comments.detectElement);
	},
	Load:function(){
		// 1. load MD5's of all elements of this page
		var url = window.location.toString();
		url = url.split("/").last().split("#").first().split("?").first();
		new Ajax.Request("ajax_commentmds.php",{postBody:"post=" + url,onComplete:function(req){
			if (req.responseText != "")
			{
				Comments.comel = eval('([' + req.responseText + '])');
				
				// 2. travel the DOM, and attach markers where there are comments
				Comments.travelNodes(document.documentElement.lastChild);
			}
		}});
	},
	travelNodes:function(el){
		if (el.innerHTML)
		{
			var elMD5 = MD5(el.innerHTML);
			if (Comments.comel.indexOf(elMD5) >= 0)
			{
				// use AJAX to find out the amount of comments for this MD5 marker:
				var url = window.location.toString();
				url = url.split("/").last().split("#").first().split("?").first();
				new Ajax.Request("ajax_commentcount.php",{postBody:"md=" + elMD5 + "&post=" + url,onComplete:function(req){
					Comments.createMarker(elMD5,el,req.responseText);
				}});
			}
			if (el.childNodes.length > 0)
			{
				for (var i=0;i<el.childNodes.length;i++)
				{
					Comments.travelNodes(el.childNodes[i]);
				}
			}
		}
	},
	detectElement:function(e){
		if (!e) var e = window.event;
		var targ;
		if (e.target) targ = e.target;
		else if (e.srcElement) targ = e.srcElement;
		if (targ.nodeType == 3) // defeat Safari bug
			targ = targ.parentNode;
		
		var blockElements = ["address","blockquote","center","code","div","dir","h1","h2","h3","h4","h5","h6","hr","pre","p","table","ol","ul","dl"]
		if (blockElements.indexOf(targ.nodeName.toLowerCase()) >= 0)
			Comments.detectComment(targ,targ);
		else
		{
			// if target = subelement of a blockElement => detect blockElement
			var targ2;
			var par = targ;
			while(targ = targ.parentNode)
			{
				if (blockElements.indexOf(targ.nodeName.toLowerCase()) >= 0)
				{
					targ2 = par;
					break;
				}
			}
			Comments.detectComment(targ,targ2);
		}
	},
	detectComment:function(orig,par){
		if (typeof par != "undefined")
		{
			var elMD5 = MD5(par.innerHTML);
			if (!$(elMD5))
				Comments.createMarker(elMD5,par,0);
			Comments.insertComment($(elMD5));
		}
	},
	createMarker:function(diggest,par,amount){
		var newel = document.createElement("span");
		var elPos = Position.cumulativeOffset(par);
		newel.style.cssText = "position:absolute;top:" + (elPos[1]-5) + "px;left:" + (Element.getStyle($("main"),"margin-left").replace("px","")*1-20) + "px;font-size:10px;font-family:Verdana;font-weight:normal;text-decoration:none;background:url('../templates/theme1/images/cbal.gif') no-repeat left center;padding:3px 3px 3px 5px;cursor:pointer;width:25px;";
		newel.innerHTML = amount;
		newel.setAttribute("id",diggest);
		newel.className = "comtag";
		Comments.addEvent(newel,"click",Comments.showComments);
		document.documentElement.lastChild.appendChild(newel);
	},
	insertComment:function(marker){
		// check if the comment div is not displaying for this block:
		if ($("showcomment"))
		{
			if (Element.getStyle(marker,"top") == Element.getStyle($("showcomment"),"top") && Element.getStyle($("showcomment"),"opacity")*1 > 0)
				Comments.hideDiv(Element.getStyle(marker,"left").replace("px","")*1,'showcomment');
		}
		
		if (!$("addcomment"))
		{
			var div = document.createElement("div");
			div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle(marker,"top") + ";left:" + Element.getStyle(marker,"left") + ";display:block;filter:alpha(opacity=10);-moz-opacity:.10;opacity:.10;overflow:hidden;";
			div.setAttribute("id","addcomment");
			// append a hidden input field with the MD5 of this marker
			var f = $("commentform").getElementsByTagName("form")[0];
			var h = document.createElement("input");
			h.setAttribute("type","hidden");
			h.setAttribute("name","mdid");
			h.setAttribute("value",marker.getAttribute("id"));
			f.appendChild(h);
			// catch the submission of the form:
			for(var i=0;i<f.elements.length;i++)
			{
				if (f.elements[i].name == "btnSubmit")
				{
					f.elements[i].setAttribute("type","button");
					f.elements[i].onclick = "Comments.catchSubmit();";
					f.elements[i].setAttribute("onclick","Comments.catchSubmit()");
				}
			}
			
			div.innerHTML = "<img src=\"../templates/theme1/images/btnClose.gif\" border=\"0\" title=\"close\" style=\"float:right;clear:both;margin-right:10px;cursor:pointer;\" onclick=\"Comments.hideDiv(" + (Element.getStyle(marker,"left").replace("px","")*1) + ",'addcomment');\" />" + $("commentform").innerHTML;
			
			// otherwise there's two times the comment form, and the invisible one gets submitted (it's the first one in the dom)
			$("commentform").parentNode.removeChild($("commentform"));
			
			document.documentElement.lastChild.appendChild(div);
			//Comments.displayCommentForm(marker);
			Comments.displayDiv(marker,'addcomment');
		}
		else
		{
			var div = $("addcomment");
			div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle(marker,"top") + ";left:" + Element.getStyle(marker,"left") + ";display:block;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;overflow:hidden;";
			// update the hidden field with the MD5
			var f = div.getElementsByTagName("form")[0]; // the form already exists, so we need to modify it
			f.elements["mdid"].value = marker.getAttribute("id");
			//Comments.displayCommentForm(marker);
			Comments.displayDiv(marker,'addcomment');
		}
	},
	catchSubmit:function(){
		var f = document.forms["addcomment"];
		var Qstring = f.serialize();
		new Ajax.Request(f.getAttribute("action"),{postBody:Qstring,onComplete:function(req){
			if (req.responseText == "")
			{
				f.reset();
				// update the marker:
				var mdid = f.elements["mdid"].value;
				$(mdid).innerHTML = ($(mdid).innerHTML*1 + 1);
				
				// if this is the first comment of this block, then update the array with all MD5s:
				if (Comments.comel.indexOf(mdid) < 0)
					Comments.comel.push(mdid);
				
				Comments.hideDiv((Element.getStyle($(mdid),"left").replace("px","")*1),'addcomment');
			}
			else
			{
				if (req.responseText == "spam")
					location = "http://www.encapsulated.org/spam.php";
				else
					alert(req.responseText);
			}
		}});
	},
	displayDiv:function(marker,divid){
		var xmov = (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 4)-(Element.getStyle(marker,"left").replace("px","")*1);
		new Effect.Parallel(
			[ new Effect.MoveBy($(divid), 0, xmov,
				{ sync: true,transition:Effect.Transitions.slowstop }),
			  new Effect.Opacity($(divid), 
				{ sync: true, to: 0.9, from: 0.0 } ),
			new Effect.Scale($(divid), 1000, {sync:true,scaleContent:false,scaleMode: { originalHeight: 35, originalWidth: (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 20) }})],
			{ duration: 0.7,afterFinish:function(effect){
				// scroll to the div
				$(divid).scrollTo();
			}}
		  );
	},
	hideDiv:function(markerleft,divid){
		var xmov = 0-((Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 4)-markerleft);
		new Effect.Parallel(
			[ new Effect.MoveBy($(divid), 0, xmov,
				{ sync: true,transition:Effect.Transitions.slowstop }),
			  new Effect.Opacity($(divid), 
				{ sync: true, to: 0.0, from: 0.9 } ),
			new Effect.Scale($(divid), 0.001, {sync:true,scaleContent:false,scaleMode: { originalHeight: Element.getStyle($(divid),"height").replace("px","")*1, originalWidth: Element.getStyle($(divid),"width").replace("px","")*1 }})],
			{ duration: 0.7,afterFinish:function(effect){
				$(divid).hide();
			}}
		  );
	},
	showComments:function(){
		var mdid = this.getAttribute("id");
		
		// if the comment form is displayed for this block, hide it first:
		var f = document.forms["addcomment"];
		if (typeof f.elements["mdid"] != "undefined")
		{
			if ($("addcomment"))
			{
				if (f.elements["mdid"].value == mdid && Element.getStyle($("addcomment"),"opacity")*1 > 0)
					Comments.hideDiv((Element.getStyle($(mdid),"left").replace("px","")*1),'addcomment');
			}
		}
		
		var url = window.location.toString();
		url = url.split("/").last().split("#").first().split("?").first();
		var div;
		if (!$("showcomment"))
			div = document.createElement("div");
		else
			div = $("showcomment");
		
		div.style.cssText = "position:absolute;width:" + (Element.getStyle(document.documentElement.lastChild,"width").replace("px","")*1 / 2) + "px;height:350px;background-color:" + Element.getStyle(document.documentElement.lastChild,"background-color") + ";border:1px solid " + Element.getStyle($("main"),"border-color") + ";top:" + Element.getStyle($(mdid),"top") + ";left:" + Element.getStyle($(mdid),"left") + ";display:block;filter:alpha(opacity=0);-moz-opacity:0;opacity:0;overflow:auto;";
		new Ajax.Request("ajax_commentdisplay.php",{postBody:"mdid=" + mdid + "&page=" + url,onComplete:function(req){
			div.innerHTML = "<img src=\"../templates/theme1/images/btnClose.gif\" border=\"0\" title=\"close\" style=\"float:right;clear:both;margin-right:10px;cursor:pointer;\" onclick=\"Comments.hideDiv(" + (Element.getStyle($(mdid),"left").replace("px","")*1) + ",'showcomment');\" />" + req.responseText;
			if (!$("showcomment"))
			{
				document.documentElement.lastChild.appendChild(div);
				div.setAttribute("id","showcomment");
			}
			//Comments.displayComments($(mdid));
			Comments.displayDiv($(mdid),'showcomment');
		}});
	},
	addEvent:function(obj,type,fn ){
		if ( obj.attachEvent ) {
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
		} else {
		  if (obj.addEventListener)
			obj.addEventListener( type, fn, false );
		}
	},
	removeEvent:function( obj, type, fn ){
		if (obj.removeEventListener)
			obj.removeEventListener( type, fn, false );
		else if (obj.detachEvent)
		{
			obj.detachEvent( "on"+type, obj[type+fn] );
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	}
};

Comments.addEvent(window,"load",Comments.init);

That’s it, the whole 247 lines. You will notice 2 functions at the bottom: addEvent and removeEvent. I won’t explain how these work. I just found them on Quirksmode, and they have been very useful to me.



Final thoughts and restrictions

Nested block elements

I usually don’t have nested block elements on my blog posts. So this script doesn’t take this situation in consideration. If you want to do this, you need to modify detectElement(), so it travels back in the DOM until it reaches the body of your document.


Restrict comments

The current script lets you place comments on undesired places too: the banner of your page, the menu, … It is possible to create restrictions in the script, but I haven’t implemented them, because this is only a tutorial/demonstration. I don’t intend on using this script on my current commenting system. If, however, I decide to use this, I’ll adjust it, and report all modifications back to my blog.


Opening and closing comment form

This causes a marker with 0 comments to be placed next to a specific block of HTML. To perfect the code, we should detect if an actual comment is placed. If not, we remove the marker again.


Commenting via regular form

The comments that are entered via the regular form, won’t display in the Javascript enhanced page. This is because those comments don’t have an MD5 hash associated with them. To make the script better, all these comments should be attached to the title of the article.

But I was happy I got everything working, and then I got lazy. So it isn’t implemented (yet).



Conclusion

The new system is unobtrusive. If you don’t have Javascript functionality in your browser, the regular form will still work, even after you modified your PHP pages to handle MD5 hashes.

The server side code that had to be written was kept to a minimum. Only some queries to fetch comments, and comment counts. All this could have been written in one larger file, but I chose not to do this, for demonstration purposes.

While not all of Jack Slocum’s functionality was implemented, I think I did a good job at mimicking the visual effects to show or hide the comments.

The system is only partially layout independent. Normally the colors are not hard coded, but some other CSS properties are. With some extra efforts, everything can be made independent too.

While the goals are mostly reached, some other conclusions are important too. The first one I consider is the use of Prototype and script.aculo.us.

Both these libraries are quite “big”, and they provide a lot of functionality you don’t really need. But I have to admit that once you learn working with them, you can do some fast coding. These libraries take away certain (difficult?) tasks, so you can concentrate better on what you want to do. This is very important for me.

Then there is the issue of the usefulness of this script. You can always find pros or cons for this kind of functionality. If you decide to implement this, you need to consider the context. For lengthy documents, I think it is good to make use of a script like this.

All things considered, this was a useful exercise, and maybe in the future I will use an updated version of this script. If you have any remarks, feel free to leave them (in the old comment form).



Sources and credits

A link to the demonstration page can be found here: http://www.encapsulated.org/tests/comments.htm


RE: Comments on parts of a web page

very helpfull

by Anonymous on 26-02-2007 06:12

RE: Comments on parts of a web page

aas

by Anonymous on 09-03-2007 20:16

RE: Comments on parts of a web page

test

by Anonymous on 12-03-2007 01:24

RE: Comments on parts of a web page

great stuff guys

by Anonymous on 25-04-2007 14:47

Good site

perishilton ]peris hilton
peris hilton*peris hilton*

by peris hilton e on 03-05-2007 18:06

Good site

perishilton ]peris hilton
google.comm*google.comm*

by google b on 04-05-2007 02:49

Good site

alter table foreign alter table foreign conti correnti bancari confronto conti correnti bancari confronto

by bgyrli on 04-05-2007 12:27

Good site

prodotto professionale pulizia prodotto professionale pulizia comunione liberazione forza italia comunione liberazione forza italia

by eyvgmx on 05-05-2007 12:07

Good site

Dating Dating RELIGION FAITH RELIGION FAITH

by manynnr on 05-05-2007 22:19

Good site

studente universitario merlino giovanni studente universitario merlino giovanni meridione situazione economica meridione situazione economica

by jiznwi on 06-05-2007 08:39

Good site

studente universitario merlino giovanni studente universitario merlino giovanni meridione situazione economica meridione situazione economica

by jiznwi on 06-05-2007 08:39

Good site

carry a cane and your hair curls dot Your gloves also are a shade
prodotti tipico*
leaning on his arm examining a copy of Raphaels Fornarina dot

by foro qxpv on 08-05-2007 16:03

Good site

manifestazione ed evento bologna manifestazione ed evento bologna storia dei cognome straniero storia dei cognome straniero

by vissep on 09-05-2007 11:25

Good site

manifestazione ed evento bologna manifestazione ed evento bologna storia dei cognome straniero storia dei cognome straniero

by vissep on 09-05-2007 11:25

Good site

associazioni per minori associazioni per minori immagine animata natale immagine animata natale

by plvdli on 10-05-2007 07:49

Good site

londra academy hotel londra academy hotel porta infrarossi esterna porta infrarossi esterna

by nundsy on 12-05-2007 13:28

Good site

londra academy hotel londra academy hotel porta infrarossi esterna porta infrarossi esterna

by nundsy on 12-05-2007 13:28

hello

torino lamiera ottone torino lamiera ottone concessioni mutuo consumatore concessioni mutuo consumatore

by gyezyp on 16-05-2007 10:20

Good site

by biagiai on 18-05-2007 07:29

hello

annunci reggio calabria annunci reggio calabria giudice minorile competente giudice minorile competente

by yfzphe on 19-05-2007 14:51

Good site

sarah beeny nude sarah beeny nude pamila nude pamila nude nude puredee nude puredee shu qui nude shu qui nude robyn moler nude robyn moler nude vampire bloodlines nude patch vampire bloodlines nude patch lita half nude lita half nude lynda wiesmeier nude lynda wiesmeier nude luanne nude luanne nude courtney peldon nude courtney peldon nude



by Britney on 19-05-2007 21:29

Good site

teen tickling teen tickling teen tabitha teen tabitha teen swimwear teen swimwear teen swimsuit teen swimsuit teen sucking teen sucking teen starlets teen starlets teen spanking teen spanking teen smoking teen smoking teens kissing teens kissing teen shemale teen shemale

by robert on 21-05-2007 19:03

hello

HUMOR HUMOR Estate Estate

by btafiqn on 24-05-2007 11:53

hello

sergio assisi elisir sergio assisi elisir ricambi moto cross ricambi moto cross

by todquv on 24-05-2007 18:58

RE: Comments on parts of a web page

test

by Anonymous on 26-05-2007 06:29

Good site

Ezines Ezines Press releases Press releases

by nnettimp on 29-05-2007 20:25

Good site

advice advice Environment Environment

by bonljok on 30-05-2007 22:17

Good site

FRUGAL LIVING FRUGAL LIVING MONEY MONEY

by bondaxm on 30-05-2007 22:17

hello

personaggi per mugen personaggi per mugen piano per la sicurezza piano per la sicurezza

by kpowza on 31-05-2007 11:50

Good site





by zeus on 01-06-2007 13:35

hello

moto scarichi moto scarichi albergo casablanca albergo casablanca

by uhmttd on 02-06-2007 09:54

Good site

download porn for free download porn for free



by Gamal on 08-06-2007 09:18

Good site

exclusive free porn exclusive free porn



by Gonzales on 09-06-2007 02:56

Good site

free cum porn free cum porn



by Goose on 09-06-2007 08:03

hello

infezione estrazione dente infezione estrazione dente fiocco neve carta fiocco neve carta

by rixwtk on 14-06-2007 01:03

Good site

hi all.

by robert on 14-06-2007 12:29

Hola faretaste

Hola faretaste
mekodinosad

by AnferTuto on 29-07-2007 06:22

RE: Comments on parts of a web page

Cool.

by Anonymous on 07-09-2007 21:49

cloth

Hello to all, its my new pages about cloth
cloth diaper
You can buy here 24\\7.

by Cloth on 21-09-2007 16:21

RE: Comments on parts of a web page

c652t

by ma634zda on 24-09-2007 05:47

RE: Comments on parts of a web page

:)

by Anonymous on 25-09-2007 23:46

RE: Comments on parts of a web page

:)

by Anonymous on 25-09-2007 23:46

RE: Comments on parts of a web page

c404t wireless security - http://freeringtones3.googlegroups.com/web/wireless-security.html verizon wireless store - http://freeringtones3.googlegroups.com/web/wireless-weather-station.html

by ma718zda on 26-09-2007 20:35

pen dog

Hello, here you can read all info about pen pal
24\\7.

by Pens on 27-09-2007 04:35

baby play pen

Hello nice blog! !!
pen
It\'s my new page.about pens.

by pens on 29-09-2007 01:24

RE: Comments on parts of a web page

c738t

by ma980zda on 02-10-2007 00:57

sofabed

Hello! nice blog!

shoes store
My sites

by mapp on 08-10-2007 12:50

RE: Comments on parts of a web page

c884t [a] http://blog.360.yahoo.com/blog-DBIy_zs7erSX5fE5Z6ythqk8oQ--?cq=1

by ma871zda on 19-10-2007 10:18

RE: Comments on parts of a web page

c898t [a] http://blog.360.yahoo.com/blog-yCw.Fhk9brwA8tL2mfkNH4ITEU4-?cq=1

by ma949zda on 19-10-2007 17:25

RE: Comments on parts of a web page

c946t [a] http://blog.360.yahoo.com/blog-WR2nGDs5bqGVdJXtAsyrgUcxcg--?cq=1

by ma19zda on 19-10-2007 20:24

RE: Comments on parts of a web page

c950t [a] http://blog.360.yahoo.com/blog-ie.WNIAieqjhEC4niAeNpksIEQ--?cq=1

by ma819zda on 19-10-2007 21:03

RE: Comments on parts of a web page

c5t [a] http://blog.360.yahoo.com/blog-mflZT9AheqRAt1c90wtvEqUvnQ--?cq=1

by ma794zda on 19-10-2007 21:16

RE: Comments on parts of a web page

c533t [a] http://blog.360.yahoo.com/blog-mUWnWNAydKpiGYfwf9QWZ8NNow--?cq=1

by ma247zda on 19-10-2007 22:41

RE: Comments on parts of a web page

c826t [a] http://blog.360.yahoo.com/blog-UOfKby85bqiTXOvfXAMaE8k8.EyHMQ-- [/a] [a] http://blog.360.yahoo.com/blog-UOfKby85bqiTXOvfXAMaE8k8.EyHMQ--?cq=1

by ma832zda on 19-10-2007 23:38

RE: Comments on parts of a web page

c121t [a] http://blog.360.yahoo.com/blog-.uaIfMA7dLQsGMUWp8J6coVwhTA-?cq=1

by ma902zda on 20-10-2007 01:03

RE: Comments on parts of a web page

c349t [a] http://blog.360.yahoo.com/blog-KAElmtQ0d6vqWjZonQBUd8KjTAkaqHE-?cq=1

by ma285zda on 20-10-2007 01:30

RE: Comments on parts of a web page

c251t [a] http://blog.360.yahoo.com/blog-g5VtEbw9YqvdQW2Rw7tmhXZRvg-- [/a] [a] http://blog.360.yahoo.com/blog-g5VtEbw9YqvdQW2Rw7tmhXZRvg--?cq=1

by ma609zda on 20-10-2007 02:08

RE: Comments on parts of a web page

c685t [a] http://blog.360.yahoo.com/blog-sID0vRM8eqs1NiGWjvXx1HlzKoTk0Q-- [/a] [a] http://blog.360.yahoo.com/blog-g5VtEbw9YqvdQW2Rw7tmhXZRvg--?cq=1

by ma662zda on 20-10-2007 02:19

RE: Comments on parts of a web page

c934t valium - http://blog.360.yahoo.com/blog-cHboJD8jfq9G6FdbQOCGjDn4nMb1qcU- order valium online - http://blog.360.yahoo.com/blog-cHboJD8jfq9G6FdbQOCGjDn4nMb1qcU-?cq=1

by ma104zda on 20-10-2007 03:15

RE: Comments on parts of a web page

c380t diazepam generic valium - http://blog.360.yahoo.com/blog-9.0XtTM7frV5DZn0wOAZgZR0qvEuFg--?cq=1

by ma118zda on 20-10-2007 03:39

RE: Comments on parts of a web page

c219t wholesale valium cheap - http://blog.360.yahoo.com/blog-9.0XtTM7frV5DZn0wOAZgZR0qvEuFg--?cq=1

by ma406zda on 20-10-2007 03:50

RE: Comments on parts of a web page

c882t what is soma 3f - http://blog.360.yahoo.com/blog-GOT1uW0mcqpulBLAULnCxPuhRRLaFfc-?cq=1

by ma8zda on 20-10-2007 04:34

RE: Comments on parts of a web page

c524t to play slot machine - http://blog.360.yahoo.com/blog-QD50tlo1dKoZruxaRx9bXarl3yq5QQ--?cq=1

by ma344zda on 20-10-2007 05:07

RE: Comments on parts of a web page

c703t online gambling indian - http://blog.360.yahoo.com/blog-3lE7quM0dqsM_FUjef76bBxGQc1F7zZXzQ--?cq=1

by ma588zda on 20-10-2007 05:44

RE: Comments on parts of a web page

c792t gambling guide - http://blog.360.yahoo.com/blog-zNVyzKI8erTWHqvGsSoo.xiqBqbNk70-?cq=1

by ma198zda on 20-10-2007 06:31

RE: Comments on parts of a web page

c230t on line gambling - http://blog.360.yahoo.com/blog-X3enk2EmcqoQOfZO3UGYhb6fLoPGfro-?cq=1

by ma802zda on 20-10-2007 06:52

RE: Comments on parts of a web page

c416t [a] http://blog.360.yahoo.com/blog-Ocwp9coldKtQb78QRKl3zVo7.g--?cq=1

by ma851zda on 20-10-2007 09:51

RE: Comments on parts of a web page

c657t [a] http://blog.360.yahoo.com/blog-E.uTeRY7frSDyywl4OA8PAJPK0GF_w-- [/a] [a] http://blog.360.yahoo.com/blog-E.uTeRY7frSDyywl4OA8PAJPK0GF_w--?cq=1

by ma132zda on 20-10-2007 10:04

RE: Comments on parts of a web page

c985t cigarette on line - http://groups.msn.com/cigarette-online42/cheapcigaretteonline.msnw cigarette online - http://groups.msn.com/cigarette-online42/buycigarette.msnw

by ma914zda on 26-10-2007 11:33

RE: Comments on parts of a web page

c347t [a] [/a]

by ma151zda on 26-10-2007 13:20

RE: Comments on parts of a web page

c195t [a] [/a]

by ma121zda on 26-10-2007 14:11

RE: Comments on parts of a web page

c377t [a] [/a]

by ma722zda on 26-10-2007 14:59

RE: Comments on parts of a web page

c282t montessori school - http://groups.msn.com/law-school48/montessorischool.msnw

by ma370zda on 26-10-2007 15:21

RE: Comments on parts of a web page

c25t [a] [/a]

by ma504zda on 26-10-2007 15:32

RE: Comments on parts of a web page

c294t

by ma323zda on 26-10-2007 15:43

RE: Comments on parts of a web page

c754t [a] [/a]

by ma244zda on 26-10-2007 15:47

RE: Comments on parts of a web page

c902t

by ma241zda on 26-10-2007 15:54

RE: Comments on parts of a web page

c230t

by ma578zda on 26-10-2007 16:06

RE: Comments on parts of a web page

c4t

by ma629zda on 26-10-2007 16:17

RE: Comments on parts of a web page

c554t [a] [/a]

by ma770zda on 26-10-2007 16:29

RE: Comments on parts of a web page

c355t [a] [/a]

by ma624zda on 26-10-2007 16:42

RE: Comments on parts of a web page

c497t

by ma353zda on 26-10-2007 16:55

RE: Comments on parts of a web page

c112t

by ma724zda on 26-10-2007 17:09

RE: Comments on parts of a web page

c222t [a] [/a]

by ma79zda on 26-10-2007 17:21

RE: Comments on parts of a web page

c800t [a] [/a]

by ma232zda on 26-10-2007 17:23

RE: Comments on parts of a web page

c433t

by ma490zda on 26-10-2007 17:32

RE: Comments on parts of a web page

c722t [a] [/a]

by ma136zda on 26-10-2007 17:44

RE: Comments on parts of a web page

c592t

by ma327zda on 26-10-2007 17:55

RE: Comments on parts of a web page

c984t

by ma458zda on 26-10-2007 18:06

RE: Comments on parts of a web page

c747t [a] [/a]

by ma247zda on 26-10-2007 18:12

RE: Comments on parts of a web page

c398t

by ma126zda on 26-10-2007 18:18

RE: Comments on parts of a web page

c47t [a] [/a]

by ma649zda on 26-10-2007 18:30

RE: Comments on parts of a web page

c528t

by ma711zda on 26-10-2007 18:43

RE: Comments on parts of a web page

c366t

by ma965zda on 26-10-2007 18:56

RE: Comments on parts of a web page

c468t [a] [/a]

by ma961zda on 26-10-2007 19:01

RE: Comments on parts of a web page

c947t [a] [/a]

by ma197zda on 26-10-2007 19:09

RE: Comments on parts of a web page

c571t

by ma230zda on 26-10-2007 19:21

RE: Comments on parts of a web page

c266t

by ma35zda on 26-10-2007 19:33

RE: Comments on parts of a web page

c257t

by ma545zda on 26-10-2007 19:45

RE: Comments on parts of a web page

c535t [a] [/a]

by ma631zda on 26-10-2007 19:51

RE: Comments on parts of a web page

c523t

by ma229zda on 26-10-2007 20:09

RE: Comments on parts of a web page

c818t [a] [/a]

by ma487zda on 26-10-2007 20:21

RE: Comments on parts of a web page

c434t

by ma94zda on 26-10-2007 20:33

RE: Comments on parts of a web page

c625t [a] [/a]

by ma957zda on 26-10-2007 20:46

RE: Comments on parts of a web page

c489t

by ma853zda on 26-10-2007 20:59

RE: Comments on parts of a web page

c987t [a] [/a]

by ma676zda on 26-10-2007 21:30

RE: Comments on parts of a web page

c948t [a] http://groups.msn.com/law-school48 [/a] [a] http://groups.msn.com/law-school48/nursingschool.msnw [/a] law school - http://groups.msn.com/law-school48

by ma868zda on 26-10-2007 21:47

RE: Comments on parts of a web page

c509t [a] http://groups.msn.com/law-school48/karateschool.msnw [/a] [a] http://groups.msn.com/law-school48/montessorischool.msnw [/a] karate school - http://groups.msn.com/law-school48/karateschool.msnw

by ma13zda on 26-10-2007 21:59

RE: Comments on parts of a web page

c879t golf school - http://groups.msn.com/online-school50/schoolloanconsolidation.msnw

by ma866zda on 26-10-2007 22:10

RE: Comments on parts of a web page

c868t school girl - http://groups.msn.com/driving-school62

by ma394zda on 26-10-2007 22:22

RE: Comments on parts of a web page

c757t charter school - http://groups.msn.com/driving-school62/charterschool1.msnw

by ma563zda on 26-10-2007 22:48

RE: Comments on parts of a web page

c280t bartending school - http://groups.msn.com/elementary-school14

by ma701zda on 26-10-2007 23:14

RE: Comments on parts of a web page

c679t school supply - http://groups.msn.com/elementary-school14/christianschool.msnw

by ma862zda on 26-10-2007 23:26

RE: Comments on parts of a web page

c422t flight school - http://groups.msn.com/elementary-school14/flightschool.msnw

by ma445zda on 26-10-2007 23:38

RE: Comments on parts of a web page

c132t [a] http://groups.msn.com/law-school48/nursingschool.msnw [/a]

by ma311zda on 26-10-2007 23:49

RE: Comments on parts of a web page

c890t [a] [/a]

by ma467zda on 27-10-2007 00:01

RE: Comments on parts of a web page

c193t [a] [/a]

by ma446zda on 27-10-2007 00:13

RE: Comments on parts of a web page

c551t [a] [/a]

by ma311zda on 27-10-2007 00:25

RE: Comments on parts of a web page

c919t free motorola ringtone - http://reddit.com/user/freemotorolaringtone

by ma314zda on 27-10-2007 00:38

RE: Comments on parts of a web page

c840t verizon ringtone - http://reddit.com/user/verizonringtone

by ma270zda on 27-10-2007 01:05

RE: Comments on parts of a web page

c914t [a] http://reddit.com/user/mp3_ringtone33 [/a] [a] http://reddit.com/user/music_ringtone94 [/a] music ringtone - http://reddit.com/user/mp3_ringtone33

by ma171zda on 27-10-2007 01:18

RE: Comments on parts of a web page

c846t [a] http://reddit.com/user/cingularwireless [/a] [a] http://reddit.com/user/dating33 [/a] cingular wireless - http://reddit.com/user/cingularwireless

by ma451zda on 27-10-2007 01:30

RE: Comments on parts of a web page

c771t adult dating - http://reddit.com/user/adultdating

by ma27zda on 27-10-2007 01:42

RE: Comments on parts of a web page

c458t online dating - http://reddit.com/user/online_dating91

by ma279zda on 27-10-2007 01:54

RE: Comments on parts of a web page

c986t free dating - http://reddit.com/user/free_dating

by ma369zda on 27-10-2007 02:07

RE: Comments on parts of a web page

c877t [a] http://reddit.com/user/internetdating [/a] [a] http://reddit.com/user/gay_dating91 [/a] internet dating - http://reddit.com/user/internetdating

by ma955zda on 27-10-2007 02:20

RE: Comments on parts of a web page

c222t dating personal - http://reddit.com/user/datingpersonal

by ma795zda on 27-10-2007 02:33

RE: Comments on parts of a web page

c500t [a] http://reddit.com/user/replica-rolex-watch [/a] [a] http://reddit.com/user/replica_handbag84 [/a] replica rolex watch - http://reddit.com/user/replica-rolex-watch

by ma772zda on 27-10-2007 02:46

RE: Comments on parts of a web page

c873t [a] http://reddit.com/user/replica-rolex [/a] [a] http://reddit.com/user/rolex-replica [/a] replica rolex - http://reddit.com/user/replica-rolex

by ma356zda on 27-10-2007 03:00

RE: Comments on parts of a web page

c796t replica - http://reddit.com/user/replica36

by ma674zda on 27-10-2007 03:13

RE: Comments on parts of a web page

c938t [a] http://reddit.com/user/rolex_replica_watch [/a] [a] http://reddit.com/user/swissreplicawatch [/a] rolex replica watch - http://reddit.com/user/rolex_replica_watch

by ma774zda on 27-10-2007 03:27

RE: Comments on parts of a web page

c206t [a] http://reddit.com/user/computer_game [/a] [a] http://reddit.com/user/game_server [/a] [a] http://reddit.com/user/video-game [/a] [a] http://reddit.com/user/free-game [/a] computer game - http://reddit.com/user/computer_game game server - http://reddit.com/user/game_server

by ma938zda on 27-10-2007 03:32

RE: Comments on parts of a web page

c989t [a] http://reddit.com/user/movie71 [/a] [a] http://reddit.com/user/freemoviedownload [/a] free movie download - http://reddit.com/user/movie71

by ma721zda on 27-10-2007 03:40

RE: Comments on parts of a web page

c742t movie theater - http://reddit.com/user/download-free-movie

by ma785zda on 27-10-2007 03:51

RE: Comments on parts of a web page

c74t adult movie - http://reddit.com/user/dvd_movie37

by ma928zda on 27-10-2007 04:04

RE: Comments on parts of a web page

c339t download movie - http://reddit.com/user/download_movie54

by ma135zda on 27-10-2007 04:16

RE: Comments on parts of a web page

c54t [a] http://reddit.com/user/free_online_game98 [/a] [a] http://reddit.com/user/download_game43 [/a] [a] http://reddit.com/user/flash_game16 [/a] [a] http://reddit.com/user/computer16 [/a] free online game - http://reddit.com/user/free_online_game98 download game - http://reddit.com/user/download_game43

by ma893zda on 27-10-2007 04:25

RE: Comments on parts of a web page

c716t watch movie online - http://reddit.com/user/watch-movie-online

by ma764zda on 27-10-2007 04:29

RE: Comments on parts of a web page

c542t music - http://reddit.com/user/music69

by ma955zda on 27-10-2007 04:43

RE: Comments on parts of a web page

c353t free music download - http://reddit.com/user/freemusicdownload

by ma281zda on 27-10-2007 04:56

RE: Comments on parts of a web page

c329t [a] http://reddit.com/user/freemusic [/a] [a] http://reddit.com/user/music-video [/a] music video - http://reddit.com/user/freemusic

by ma522zda on 27-10-2007 05:10

RE: Comments on parts of a web page

c201t [a] [/a]

by ma19zda on 27-10-2007 05:18

RE: Comments on parts of a web page

c544t pop music - http://reddit.com/user/pop_music

by ma859zda on 27-10-2007 05:24

RE: Comments on parts of a web page

c174t [a] http://reddit.com/user/downloadable_music [/a]

by ma458zda on 27-10-2007 05:37

RE: Comments on parts of a web page

c678t [a] http://reddit.com/user/home69 [/a] [a] http://reddit.com/user/home-based-business [/a] home - http://reddit.com/user/home69

by ma452zda on 27-10-2007 05:50

RE: Comments on parts of a web page

c376t work from home - http://reddit.com/user/work_from_home98

by ma492zda on 27-10-2007 06:03

RE: Comments on parts of a web page

c564t [a] http://reddit.com/user/dance_music [/a]

by ma198zda on 27-10-2007 06:13

RE: Comments on parts of a web page

c186t

by ma160zda on 27-10-2007 06:14

RE: Comments on parts of a web page

c148t [a] [/a]

by ma454zda on 27-10-2007 06:27

RE: Comments on parts of a web page

c763t

by ma60zda on 27-10-2007 06:40

RE: Comments on parts of a web page

c874t

by ma870zda on 27-10-2007 06:54

RE: Comments on parts of a web page

c553t [a] [/a]

by ma151zda on 27-10-2007 07:08

RE: Comments on parts of a web page

c411t

by ma988zda on 27-10-2007 07:21

RE: Comments on parts of a web page

c374t

by ma112zda on 27-10-2007 07:33

RE: Comments on parts of a web page

c684t

by ma517zda on 27-10-2007 07:45

RE: Comments on parts of a web page

c673t [a] [/a]

by ma416zda on 27-10-2007 07:55

RE: Comments on parts of a web page

c208t

by ma553zda on 27-10-2007 07:58

RE: Comments on parts of a web page

c821t

by ma407zda on 27-10-2007 08:10

RE: Comments on parts of a web page

c734t [a] [/a]

by ma360zda on 27-10-2007 08:22

RE: Comments on parts of a web page

c196t

by ma583zda on 27-10-2007 08:36

RE: Comments on parts of a web page

c747t

by ma722zda on 27-10-2007 08:49

RE: Comments on parts of a web page

c841t

by ma476zda on 27-10-2007 09:04

RE: Comments on parts of a web page

c856t

by ma1zda on 27-10-2007 09:17

RE: Comments on parts of a web page

c838t [a] [/a]

by ma717zda on 27-10-2007 09:29

RE: Comments on parts of a web page

c171t [a] [/a]

by ma929zda on 27-10-2007 09:38

RE: Comments on parts of a web page

c380t [a] [/a]

by ma532zda on 27-10-2007 09:41

RE: Comments on parts of a web page

c150t

by ma571zda on 27-10-2007 09:53

RE: Comments on parts of a web page

c425t

by ma139zda on 27-10-2007 10:06

RE: Comments on parts of a web page

c804t

by ma726zda on 27-10-2007 10:18

RE: Comments on parts of a web page

c472t [a] [/a]

by ma296zda on 27-10-2007 10:29

RE: Comments on parts of a web page

c188t

by ma322zda on 27-10-2007 10:31

RE: Comments on parts of a web page

c838t

by ma858zda on 27-10-2007 10:44

RE: Comments on parts of a web page

c445t

by ma578zda on 27-10-2007 10:58

RE: Comments on parts of a web page

c290t

by ma232zda on 27-10-2007 11:11

RE: Comments on parts of a web page

c478t

by ma459zda on 27-10-2007 11:11

RE: Comments on parts of a web page

c6t [a] [/a]

by ma449zda on 27-10-2007 11:19

RE: Comments on parts of a web page

c270t

by ma168zda on 27-10-2007 11:24

RE: Comments on parts of a web page

c804t

by ma698zda on 27-10-2007 11:36

RE: Comments on parts of a web page

c95t [a] [/a]

by ma793zda on 27-10-2007 11:48

RE: Comments on parts of a web page

c582t [a] [/a]

by ma879zda on 27-10-2007 12:00

RE: Comments on parts of a web page

c251t [a] [/a]

by ma526zda on 27-10-2007 12:12

RE: Comments on parts of a web page

c81t [a] [/a]

by ma595zda on 27-10-2007 12:25

RE: Comments on parts of a web page

c241t [a] [/a]

by ma752zda on 27-10-2007 12:38

RE: Comments on parts of a web page

c449t [a] [/a]

by ma121zda on 27-10-2007 12:52

RE: Comments on parts of a web page

c127t

by ma257zda on 27-10-2007 13:06

RE: Comments on parts of a web page

c700t

by ma675zda on 27-10-2007 13:19

RE: Comments on parts of a web page

c39t

by ma798zda on 27-10-2007 13:30

RE: Comments on parts of a web page

c554t [a] [/a]

by ma381zda on 27-10-2007 13:42

RE: Comments on parts of a web page

c566t [a] [/a]

by ma471zda on 27-10-2007 13:47

RE: Comments on parts of a web page

c757t [a] [/a]

by ma584zda on 27-10-2007 13:54

RE: Comments on parts of a web page

c22t

by ma599zda on 27-10-2007 14:06

RE: Comments on parts of a web page

c176t

by ma500zda on 27-10-2007 14:18

RE: Comments on parts of a web page

c508t

by ma384zda on 27-10-2007 14:31

RE: Comments on parts of a web page

c780t [a] [/a]

by ma60zda on 27-10-2007 14:35

RE: Comments on parts of a web page

c938t

by ma262zda on 27-10-2007 14:44

RE: Comments on parts of a web page

c688t

by ma228zda on 27-10-2007 14:58

RE: Comments on parts of a web page

c282t

by ma35zda on 27-10-2007 15:11

RE: Comments on parts of a web page

c85t

by ma413zda on 27-10-2007 15:23

RE: Comments on parts of a web page

c915t

by ma953zda on 27-10-2007 15:46

RE: Comments on parts of a web page

c937t [a] [/a]

by ma37zda on 27-10-2007 15:58

RE: Comments on parts of a web page

c894t [a] [/a]

by ma73zda on 27-10-2007 16:09

RE: Comments on parts of a web page

c252t [a] [/a]

by ma178zda on 27-10-2007 16:12

RE: Comments on parts of a web page

c419t

by ma369zda on 27-10-2007 16:21

RE: Comments on parts of a web page

c388t

by ma167zda on 27-10-2007 16:34

RE: Comments on parts of a web page

c83t

by ma666zda on 27-10-2007 16:47

RE: Comments on parts of a web page

c50t [a] [/a]

by ma718zda on 27-10-2007 17:00

RE: Comments on parts of a web page

c786t [a] [/a]

by ma154zda on 27-10-2007 17:01

RE: Comments on parts of a web page

c605t

by ma383zda on 27-10-2007 17:13

RE: Comments on parts of a web page

c871t [a] [/a]

by ma570zda on 27-10-2007 17:25

RE: Comments on parts of a web page

c114t

by ma749zda on 27-10-2007 17:38

RE: Comments on parts of a web page

c974t

by ma849zda on 27-10-2007 17:50

RE: Comments on parts of a web page

c617t [a] [/a]

by ma628zda on 27-10-2007 17:51

RE: Comments on parts of a web page

c706t [a] [/a]

by ma407zda on 27-10-2007 18:01

RE: Comments on parts of a web page

c661t

by ma459zda on 27-10-2007 18:13

RE: Comments on parts of a web page

c150t

by ma289zda on 27-10-2007 18:25

RE: Comments on parts of a web page

c150t

by ma289zda on 27-10-2007 18:37

RE: Comments on parts of a web page

c51t [a] [/a]

by ma760zda on 27-10-2007 18:50

RE: Comments on parts of a web page

c242t

by ma36zda on 27-10-2007 19:04

RE: Comments on parts of a web page

c301t [a] [/a]

by ma485zda on 27-10-2007 19:17

RE: Comments on parts of a web page

c114t

by ma749zda on 27-10-2007 19:28

RE: Comments on parts of a web page

c347t [a] [/a]

by ma210zda on 27-10-2007 19:40

RE: Comments on parts of a web page

c560t [a] [/a]

by ma787zda on 27-10-2007 19:52

RE: Comments on parts of a web page

c125t

by ma861zda on 27-10-2007 20:03

RE: Comments on parts of a web page

c533t [a] [/a]

by ma149zda on 27-10-2007 20:15

RE: Comments on parts of a web page

c15t [a] [/a]

by ma705zda on 27-10-2007 20:18

RE: Comments on parts of a web page

c629t [a] [/a]

by ma848zda on 27-10-2007 20:26

RE: Comments on parts of a web page

c7t [a] http://reddit.com/user/computer_virus12 [/a] [a] http://reddit.com/user/computergame [/a] computer virus - http://reddit.com/user/computer_virus12

by ma393zda on 27-10-2007 20:40

RE: Comments on parts of a web page

c269t [a] http://reddit.com/user/free-computer-game [/a] [a] http://reddit.com/user/computer-electronic [/a] computer electronic - http://reddit.com/user/free-computer-game

by ma9zda on 27-10-2007 20:53

RE: Comments on parts of a web page

c383t [a] http://reddit.com/user/computer_graphic37 [/a] [a] http://reddit.com/user/computergaming [/a] computer gaming - http://reddit.com/user/computer_graphic37

by ma940zda on 27-10-2007 21:07

RE: Comments on parts of a web page

c874t computer training - http://reddit.com/user/computer_training84

by ma550zda on 27-10-2007 21:20

RE: Comments on parts of a web page

c359t computer desktop - http://reddit.com/user/computer_desktop76

by ma765zda on 27-10-2007 21:32

RE: Comments on parts of a web page

c266t [a] http://reddit.com/user/ticket60 [/a] [a] http://reddit.com/user/cheap-ticket [/a] ticket - http://reddit.com/user/ticket60

by ma424zda on 27-10-2007 21:43

RE: Comments on parts of a web page

c949t [a] http://reddit.com/user/concertticket [/a] [a] http://reddit.com/user/cheap_airline_ticket [/a] concert ticket - http://reddit.com/user/concertticket

by ma810zda on 27-10-2007 21:55

RE: Comments on parts of a web page

c514t sports ticket - http://reddit.com/user/sports_ticket81

by ma507zda on 27-10-2007 22:07

RE: Comments on parts of a web page

c968t [a] http://reddit.com/user/air-travel [/a] [a] http://reddit.com/user/air_travel_discount [/a] air travel - http://reddit.com/user/air-travel

by ma682zda on 27-10-2007 22:31

RE: Comments on parts of a web page

c595t adventure travel - http://reddit.com/user/adventure-travel

by ma664zda on 27-10-2007 22:44

RE: Comments on parts of a web page

c259t travel agency - http://reddit.com/user/travel_agency17 travel planning - http://reddit.com/user/travel_planning98

by ma779zda on 27-10-2007 22:57

RE: Comments on parts of a web page

c356t casino - http://reddit.com/user/casino63 travel guide - http://reddit.com/user/onlinecasino

by ma43zda on 27-10-2007 23:10

RE: Comments on parts of a web page

c706t [a] http://reddit.com/user/casino_poker34 [/a] [a] http://reddit.com/user/onlinecasinogambling [/a] [a] http://reddit.com/user/lasvegascasino [/a] [a] http://reddit.com/user/free_casino [/a] casino poker - http://reddit.com/user/casino_poker34 online casino gambling - http://reddit.com/user/onlinecasinogambling

by ma519zda on 27-10-2007 23:23

RE: Comments on parts of a web page

c812t casino vacation - http://reddit.com/user/casino_vacation30 casino game - http://reddit.com/user/casino-game

by ma349zda on 27-10-2007 23:35

RE: Comments on parts of a web page

c715t [a] http://reddit.com/user/buy_hydrocodone85 [/a] [a] http://reddit.com/user/hydrocodone24 [/a] buy hydrocodone - http://reddit.com/user/buy_hydrocodone85

by ma591zda on 28-10-2007 01:18

RE: Comments on parts of a web page

c594t online gambling casino - http://reddit.com/user/online_gambling_sit7 online gambling site - http://reddit.com/user/gambling_site77

by ma229zda on 28-10-2007 02:28

RE: Comments on parts of a web page

c925t bet - http://reddit.com/user/online_bet37 online bet - http://reddit.com/user/football_bet59

by ma589zda on 28-10-2007 02:42

RE: Comments on parts of a web page

c885t [a] [/a]

by ma359zda on 28-10-2007 08:56

RE: Comments on parts of a web page

c586t

by ma912zda on 28-10-2007 09:10

RE: Comments on parts of a web page

c84t [a] [/a]

by ma176zda on 28-10-2007 09:23

RE: Comments on parts of a web page

c311t [a] [/a]

by ma80zda on 28-10-2007 09:35

RE: Comments on parts of a web page

c207t [a] [/a]

by ma646zda on 28-10-2007 09:48

RE: Comments on parts of a web page

c197t

by ma455zda on 28-10-2007 10:00

RE: Comments on parts of a web page

c604t

by ma19zda on 28-10-2007 10:12

RE: Comments on parts of a web page

c645t [a] [/a]

by ma257zda on 28-10-2007 10:25

RE: Comments on parts of a web page

c192t [a] [/a]

by ma671zda on 28-10-2007 10:38

RE: Comments on parts of a web page

c782t [a] [/a]

by ma686zda on 28-10-2007 22:37

RE: Comments on parts of a web page

c591t [a] [/a]

by ma520zda on 29-10-2007 10:55

RE: Comments on parts of a web page

c338t [a] [/a]

by ma380zda on 01-11-2007 08:17

RE: Comments on parts of a web page

c871t [a] [/a]

by ma955zda on 01-11-2007 08:18

RE: Comments on parts of a web page

c798t [a] [/a]

by ma43zda on 01-11-2007 08:31

RE: Comments on parts of a web page

c713t

by ma291zda on 01-11-2007 08:43

RE: Comments on parts of a web page

c833t

by ma319zda on 01-11-2007 08:55

RE: Comments on parts of a web page

c236t

by ma765zda on 01-11-2007 09:07

RE: Comments on parts of a web page

c190t [a] [/a]

by ma368zda on 01-11-2007 09:20

RE: Comments on parts of a web page

c473t [a] [/a]

by ma690zda on 01-11-2007 09:32

RE: Comments on parts of a web page

c541t [a] [/a]

by ma223zda on 01-11-2007 09:45

RE: Comments on parts of a web page

c302t

by ma547zda on 01-11-2007 09:58

RE: Comments on parts of a web page

c879t [a] [/a]

by ma266zda on 01-11-2007 10:01

RE: Comments on parts of a web page

c382t

by ma215zda on 01-11-2007 10:12

RE: Comments on parts of a web page

c114t [a] [/a]

by ma168zda on 01-11-2007 10:25

RE: Comments on parts of a web page

c80t

by ma540zda on 01-11-2007 10:36

RE: Comments on parts of a web page

c863t [a] [/a]

by ma613zda on 01-11-2007 10:49

RE: Comments on parts of a web page

c857t [a] [/a]

by ma691zda on 01-11-2007 11:01

RE: Comments on parts of a web page

c988t

by ma11zda on 01-11-2007 11:13

RE: Comments on parts of a web page

c117t [a] [/a]

by ma8zda on 01-11-2007 11:25

RE: Comments on parts of a web page

c609t [a] [/a]

by ma203zda on 01-11-2007 11:44

RE: Comments on parts of a web page

c347t [a] [/a]

by ma850zda on 02-11-2007 00:14

RE: Comments on parts of a web page

c313t [a] [/a]

by ma658zda on 02-11-2007 00:26

RE: Comments on parts of a web page

c294t [a] [/a]

by ma57zda on 02-11-2007 00:38

RE: Comments on parts of a web page

c361t

by ma970zda on 02-11-2007 00:50

RE: Comments on parts of a web page

c30t [a] [/a]

by ma571zda on 02-11-2007 01:03

RE: Comments on parts of a web page

c386t

by ma745zda on 02-11-2007 01:15

RE: Comments on parts of a web page

c641t [a] [/a]

by ma622zda on 02-11-2007 01:28

RE: Comments on parts of a web page

c625t

by ma454zda on 02-11-2007 01:41

RE: Comments on parts of a web page

c515t [a] [/a]

by ma869zda on 02-11-2007 01:54

RE: Comments on parts of a web page

c723t

by ma23zda on 02-11-2007 02:08

RE: Comments on parts of a web page

c917t

by ma695zda on 02-11-2007 02:21

RE: Comments on parts of a web page

c462t [a] [/a]

by ma644zda on 02-11-2007 02:33

RE: Comments on parts of a web page

c997t

by ma620zda on 02-11-2007 02:45

RE: Comments on parts of a web page

c138t [a] [/a]

by ma798zda on 02-11-2007 02:57

RE: Comments on parts of a web page

c606t

by ma365zda on 02-11-2007 03:10

RE: Comments on parts of a web page

c864t

by ma268zda on 02-11-2007 03:23

RE: Comments on parts of a web page

c735t

by ma466zda on 02-11-2007 03:37

RE: Comments on parts of a web page

c692t

by ma621zda on 02-11-2007 04:03

RE: Comments on parts of a web page

c29t [a] [/a]

by ma171zda on 02-11-2007 04:17

RE: Comments on parts of a web page

c626t [a] [/a]

by ma228zda on 02-11-2007 04:29

RE: Comments on parts of a web page

c259t [a] [/a]

by ma661zda on 02-11-2007 04:41

RE: Comments on parts of a web page

c368t [a] [/a]

by ma515zda on 02-11-2007 04:54

RE: Comments on parts of a web page

c869t

by ma58zda on 02-11-2007 05:06

RE: Comments on parts of a web page

c669t [a] [/a]

by ma497zda on 02-11-2007 05:19

RE: Comments on parts of a web page

c6t

by ma449zda on 02-11-2007 05:32

RE: Comments on parts of a web page

c72t [a] [/a]

by ma53zda on 02-11-2007 05:46

RE: Comments on parts of a web page

c661t [a] [/a]

by ma32zda on 02-11-2007 06:00

RE: Comments on parts of a web page

c30t

by ma565zda on 02-11-2007 06:14

RE: Comments on parts of a web page

c887t [a] [/a]

by ma583zda on 02-11-2007 06:26

RE: Comments on parts of a web page

c858t

by ma259zda on 02-11-2007 06:40

RE: Comments on parts of a web page

c136t [a] [/a]