Stanford University Wiki
Advertisement

Overview[]

Imagine you own a web blog and each time you write an article for your blog, you always expect comments from others. Normally, in most of the web blogs, there will be comment sections right after each article. Now, imagine that you have a long article, so when your friends read it and want to give some comments on a paragraph or a particular sentence, they have to go the end of the article and click "add comment" and probably have to copy & paste the sentence they want to comments and write their comments next to it. Now, for the readers (maybe the blog owner himself), when they read the comments, they have to scroll up to find the area that the comment is talking about to refresh their memory.

It would be really nice for the readers to be able to read the comments while they are reading the article without scrolling up and down!

This is what this project is about.

Evolution of Web 2.0 has shown how powerful information can be obtained from the website surfers (visitors) in the form of comments, feedback, rating and additional contents.

Our application provides a hassle free interface for website developers to get feedback and comments (currently in the form of text) from their visitors. Our commenting application takes care of all the sub-tasks involved. It provides a clean interface for the visitors to write comments, storing the comments and displaying the comments. The interface is non-intrusive which preserves the original website design. It also doesn't interfere with visitors' browsing experience with unwanted pop-ups. Only if the visitor wishes to see comments and share his thought or comment on certain item on the web-page, he can do so by some quick intuitive actions. Each word in a DOM element can be specifically commented, which allows the comments to very targeted and precise.

As mentioned the aim of this project was make this interaction as non-intrusive as possible to ensure improved level of browsing experience. Also, project was kept as modular and portable as possible to make it easy to use for the developers, regardless of their website structure, by including the script and calling a function.

Implementation involves both browser-side and server-side technologies. Server was required to store and retrieve visitor comments and browser handles the interaction with the visitor and communicates with server to fetch and send comments

How To Use (Developer)[]

Developers can use this commenting interface by simply embedding one JavaScript (bootstrap.js) and they have to provide a link to the reverse proxy for cross-domain communication. As this application involves communication with our server for fetching and storing comments, which modifies the DOM structure of the web-page. This cross-domain communication is handled using PHP servlet, so the website need to host in a servlet enabled server. Further discussion is in Stumbling point below. Here is an example of what the developer has to include in the web page:

  <script language="JavaScript" type="text/JavaScript">var proxy="http://cgi.stanford.edu/~noraseth/prox3.php";</script>
  <script type="text/javascript" src="http://128.12.142.225/349/comment_script/bootstrap.js"></script>

How To Use (Visitor)[]

Visitor has the option of enabling and disabling the commenting interface all the while he is browsing the website. Whenever visitors hover mouse on the top, a drop down box is presented to the visitor, using which visitor can choose to enable the mode to write and view comment by the following ways:

Write a Comment[]

Once the commenting mode is enabled by the visitor, visitor can write comments by double clicking on any word in a DOM element. Another text box is presented to the visitor to write and post the comment. This comment is stored in our server.

View Comments[]

Similarly, once the commenting mode is enabled by the visitor, the entire DOM elements that have been already commented are highlighted. Visitor can double click on any of the highlighted items and a pop-up box with comments for the item is presented.

Implementation[]

Find Target "Token"[]

Problem[]

Our application allows visitors to comment on each individual word in a DOM element, so when a visitor clicks a word, we need to find out exactly which word in the target element the visitor clicks on. This requires token-level event handling. However, the current DOM event object only provides information about target "element" instead of target "token". We only know which element a visitor clicks on but have no idea exactly which word the visitor is interested in. We need a mechanism to locate that target token.

Approach #1[]

The first approach we took was to use the absolute position of the target element and the mouse position to approximate which word within that element a visitor intends to comment on. For example, the position of a target element is (0,0) and the mouse position is (20,20). Given the element's dimension and the text font size, we probably can say the target token is the second word of the second line.

The advantage of this approach is that it's completely non-intrusive, meaning we don't need to change the client page at all. But the downside is that this is an approximation after all, it's highly inaccurate. Sometimes due to rounding errors, it can be several words off. We tried this approach but failed miserably.

Approach #2[]

So we decided to switch to another approach, in which we tokenize every text node and make each token an element. That way we can handle token-level events just as we handle element-level events.

The advantage of this approach is that it's easy to implement and 100% accurate, but with this approach we have to change the DOM structure of client pages and may or may not change the feel-and-look as a result.


Identify Target "Token"[]

Once we locate the target token, we need to uniquely identify it so that the comments on the token can be stored into and retrieved from the backend database. We use a combination of domain, path, and DOM hierarchy as the key. For example, the third word in the first child node of the xyz.com index page can be identified as "www.xyz.com/index.html#1,3", where "www.xyz.com" is the domain, "/index.htm" is the path, and everything after the # sign indicates the DOM hierarchy. In this case, 1 says the target token is in the 1st child of body, and 3 tells you that it's the second word in that element.

Server Communication[]

As discussed above, when web masters want to include the commenting functionality on their web pages, they just have to include two lines of code, which will link to our JavaScript in the pages. Then, we the visitor wants to add new comments or retrieve comments, the JavaScript code will communicate with the commenting server with appropriate information. That is, all of the comments associated to each page/each DOM element will be kept at our server. To create the web service, we use ASP.NET to create a SOAP web service.

Here is the example of the service our server provides.

To request the comment associated to a (domain, path, DOM element), the client has to send HTTP Request using POST command in the following format:

POST /349/comment_service.asmx HTTP/1.1
Host: 128.12.142.225
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope>
  <soap12:Body>
    <GetLastComment xmlns="http://tempuri.org/">
      <domain>wwww.349w.com</domain>
      <path>intro.html</path>
      <key>1;3;4;3;5</key>
    </GetLastComment>
  </soap12:Body>
</soap12:Envelope>

Then, the server will respond this:

<soap:Envelope>
  <soap:Body>
    <GetLastCommentResponse xmlns="http://tempuri.org/">
      <GetLastCommentResult>
        <type>Text</type>
        <value>Hi How are you?</value>
      </GetLastCommentResult>
    </GetLastCommentResponse>
  </soap:Body>
</soap:Envelope>

So, the client can extract the comment (value tag) from the XML response.

Now, let's see how to create this using ASP.NET. It is pretty simple. First, we have to create a .NET web service project. Next, we can just define the function that has the arguments and return value we need and ASP.NET will take care of the SOAP communication protocol and data serialization.

namespace CommentWebService {
    [WebService(Namespace = "http://128.12.142.225/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class Service1 : System.Web.Services.WebService {
        public struct LastComment {
            public string type;
            public string value;
        }

        [WebMethod]
        public LastComment GetLastComment(string domain, string path, string key)
        {
            CommentsManager c = new CommentsManager();
            DataRow[] rows;
            rows = c.dsComments.tblComments.Select(
                " domain = '" + domain + "'" +
                " AND path = '" + path + "'" +
                " AND key = '" + key + "'" +
                "", "id DESC");

            LastComment l = new LastComment();
            l.type = "";
            l.value = "";
            if (rows.Length > 0)
            {
                l.type = rows[0]["type"].ToString();
                l.value = rows[0]["value"].ToString();
            }
            return l;
        }
    }
}


After we compile the code and place in the WWW folder of the webserver, our web service is up and running!

Stumbling point[]

Cross-domain communication[]

Communicating between different domains is a famous issue when developing reusable, interactive web applications. In our case, our JavaScript in the client page (say, www.349w.com) cannot send AJAX HTTP Request to the commenting server (say, www.commentserver.com) and that is the problem since all comments are kept in the database at www.commentserver.com. There are two ways to work around this issue.

  • Use plug-in:

First, we can develop a Firefox plug-in and the client page can use plug-in as a proxy to communicate to www.commentserver.com. Since binary plug-in is an installed application on the browser, it can arbitrarily open socket connection to communicate with www.commentserver.com. The disadvantage of this approach is all end-users have to install plug-in before starting using the page that has commenting service enabled.

  • Use reverse proxy:

The second approach that does not involve end-users installing anything on their machines is to use a proxy service that runs on the same domain the page is hosted. For example, in this case, we need the webmaster to provide the link to the proxy (say, www.349w.com/proxy.php). Then, all communications that our JavaScript will send to www.commentserver.com will be sent through www.349w.com/proxy.php. Then, when the commenting server responds back to the proxy, the proxy will forward the response to the client. Our implementation uses this approach since it's more convenient for the end-users.

Preserve style during tokenization[]

If we had simply made each token an element, all the spaces between the words would have been gone. Therefore, when tokenizing a text node, we need to remember not only the tokens but also the spaces between the tokens. When reconstructing the DOM hierarchy, we need to insert those space characters between the token elements.

Merely preserving the spaces is not sufficient to preserve the feel-and-look of a page. Modifying the DOM hierarchy and inserting new elements inevitably lead browsers to render it somewhat differently. This is definitely one of the areas we need to improve on in the future. It is important to remember, however, the visitors can always disable the comment feature to restore the original page.

Future Work[]

The followings are can be easily implemented as an extension to our current running version.

  • User Authentication: Currently, we allow anyone to view and post comment on the website, this can be restricted by an authentication process for the user, hence allowing website developer to control on who can post comments.
  • Moderation/Authorization: Currently, we do not support deletion or any sort approval from the website developer for the comments. This can potentially lead to spam and unwanted comments. To avoid this we can request approval from the website developer before publishing the user comment. Also, we can provide website developer and comment author the option of deleting comments.
  • Multimedia Support: Currently, we are only supporting text comments. But this can be extended to accept multimedia comments from the user in the form of images, audio and videos uploads.
  • More Styling Options: Currently, when the user wishes to see the commented items, commented text is highlighted (style defined in comment.css) by red color and bold styling. We can provide with more styles to blend better with the web-page.

Strengths[]

From the perspective of the visitor, our commenting interface provides a rich way for the visitor to share his thoughts, comments and feedback about the website with the developer and other visitors. This interaction is non intrusive, with the visitor always having the option to disable the commenting mode. Double click action is very intuitive. We have tried to minimize the interference of the pop up boxes in the website browsing experience.

Also, we allow comments for any DOM element, this granularity to single word is not provided by any conventional commenting methods (which are limited to web-pages, blog entries, news-article, videos, images, etc). This allows a way to write very specific and precise comment and feedback which can be helpful to both developer and other visitors.

From the perspective of the developer, this is very easy to use, all he has to do is to embed the comment.js and comment.css and all the rest is taken care including storing and fetching of comments for each of the specific DOM element on the website.

Another important point is that when visitors comment on a particular word in a page, essentially they are tagging the page. Based on the frequency of comments and other parameters, we probably can infer which key words are representative of this page. Moreover, these relevancy measures are based on real visitor inputs instead of on some statistic models or AI engines. This provides valuable information for an information retrieval (IR) engine such as Google. With the comments we offer, IR engines can be further extended to take into consideration not only the terms appearing in a page but also the comments on that page.

Finally, with an authentication mechanism in place, our application can build a user profile and have a precise idea of what kind of person he/she is. Since all the data is stored on our servers, we have the information about what kind of websites a user visited and what kind of words he/she is interested in. This allows us to target the user and provide better services.

Weaknesses[]

  • The tokenization process, which was incorporated to identify the selections made by the user, sometimes changes the websites slightly. This is one of the undesirable outcomes, as site developers and users might not like the changes.
  • The necessity of servlet enable server for hosting the website can be a bottleneck in the usage of this commenting interface.
  • Also, the features mentioned in future work which are currently not present in our running demo and, so, are weaknesses which can be overcome by extending the scripts to support the above mentioned options.
  • It does not support dynamic web pages. Since we associate the comments with DOM element location, if the web site structure is significantly changed, our DOM key will be meaningless. However, some dynamic web pages such as blogs could potentially be our customers since blogs normally keep appending the content and the end of the page or at the end of each DOM section. That is, if after changes, the website has the same overall DOM structure (i.e., just minor changes in the innermost levels), our commenting service will run without any issues.
  • Currently our application only supports Firefox

Examples[]

Advertisement