Rough Book

random musings of just another computer nerd

Month: July, 2005

You Can Start Looking Now

I know I haven’t posted in a while. That’s mainly because I’ve been busy and lazy – an interesting combination. I was having my military training over the past two weeks, so I really didn’t have time to update my journal. In addition, my DSL service is being really flaky. I’m dropping connection and then my modem refuses to retrain. I’m talking to Qwest right now. I’m pretty sure it’s their fault. Hopefully they’ll fix it.

Anyway, so I had a few conversations with my parents over the past few weeks, and the subject was marriage. No, it wasn’t something like “Son, we need to find you a girl now.” It was more like “Hey, you can start looking now if you want”. I talked about this a little bit sometime ago, and I was thinking of talking to my parents about it as well. Truth be told, I guess I’m not averse to “settling down”. The fact of the matter is that I would really like some female companionship of a serious and lasting nature in my life right now. Merely dating wouldn’t do that for me. It used to bother me that I never really dated anyone during my college years. But in retrospect, I’m glad I didn’t. I can totally see myself neglecting my academics. Also, the fact that I had no woman, meant that I wouldn’t be spending any time with her. Which meant that I had time to pursue my nerdy pursuits. Which in turn led to me picking up some really useful skills, and accomplishing some really neat things which finally led to an internship, and then, a job at Intel. So in the end, it’s not all that bad.

Actually my parents weren’t the first people to tell me that I could start looking. It was my aunt. I was in California over the 4th of July weekend, and my aunt said that my cousin and I should “start looking” now so that we “could get married when the time comes”. I thought it was a little funny, and actually I didn’t find her idea that far-fetched. I have been sort of “pseudo-looking” – I just haven’t found anyone. So I half-jokingly tell this to my parents and they said “Oh yeah, you should start looking!” So then I decided to see what my options were. Of course, they would ideally want me to marry a Hindu, Nair, Malayalee girl. But what about a girl from another culture? A Tamilian girl perhaps? I asked them. Their response was measured, and I guess, cautious. My father only told me that it may work out initially but that difficulties could arise once children came into the picture, or possibly, even before that, and that there are greater risks. So I’m not sure if they meant it was ok or not ok for me to look for girls from another culture. My parents have never really talked to me that much about marriage, and so I was really happy to see how open-minded they were about the issue. To those who might be thinking that this has the makings of an arranged marriage, it really doesn’t. First of all, they aren’t the ones looking for a girl – they’ve left it up to me. Although, I do know that if they come across a girl they think I might like, they may recommend I get in touch with her. I don’t see that as bad either, since it’s like my parents are hooking me up. The funny part was when my father told me to put myself up on Kerala Matrimonials. He said “Oh, it’s just like a dating service!” I thought that was funny. I don’t think I’m ready for that yet though…

I’m keeping an open mind and also keeping my options open. I guess if I try and concentrate too much on one particular goal, it may close out other possibilities. If I need to find a nice Nair girl, it’s harder for me, because there are very few Malayalees in Arizona. But I hear there are many in California and Texas. Oh well. I don’t think I’ll actively go around looking, but I’ll keep my eyes and ears open. At any rate, there’s no point in looking now, because I’m going to be in Iraq for a year. Now what are the odds of meeting a Hindu, Nair, Malayalee girl there? I’d laugh if I met one – in the Army nonetheless!

Mailserver troubles

I was running portupgrade -a on my FreeBSD machine when I discovered some problems. The first problem had to do with the size of my mail queue. I kept getting a “452 Insufficient system storage” message from Microsoft Outlook, along with an error code of 0x800CCC0F. I am running Postfix, and so had to edit main.cf to read:

message_size_limit = 51200000
mailbox_size_limit = 51200000
queue_minfree      = 102400000

Those sizes may seem rather large, but I’ve got room to spare. This got rid of the “Insufficient storage” errors, but then I got a new error. Outlook said that the connection to the mailserver was “unexpectedly interrupted” when trying to receive mail. This was a problem with my POP3 daemon. I wasn’t unable to telnet to port 110, so it seemed like it wasn’t running. I use Courier-IMAP, which comes with a POP3 daemon. I tried to rebuild the port, but it complained that the port was broken. So I had to figure out how to downgrade it (and then upgrade it):

[email protected] ~
$ pkg_delete courier-imap\*
[email protected] ~
$ pkg_add -r courier-imap
[email protected] ~
$ portupgrade courier-imap

The last step gave me some trouble. It actually didn’t install (it should – but I don’t know why it didn’t), so I had to go in and manually install it from the ports tree. I don’t know what happened, but running portupgrade on all the installed ports caused some sort of problem.

Once the port was installed, I still wasn’t able to get it to run. I tried looking for documentation, but I couldn’t find any really. The problem had to do with the authdaemond daemon. It wasn’t starting up. However, once I added courier_authdaemond_enable=”YES” to /etc/rc.conf, it started working fine.

I don’t know what it is with setting up MTA’s – I’ve always had trouble setting mine up. They’re the first things to break, and the last things to get fixed.

innerHTML alternative for XHTML documents in Firefox

I finally figured out an alternative to using innerHTML for an XHTML document in Firefox. <a target = “_blank” href = http://vivin.net/2005/06/30/innerhtml-and-createcontextualfragment-problems-when-firefox-renders-xhtml/”>Earlier I talked about trying to use innerHTML on my website, and how I ran into problems. Basically, the property is not supported for XHTML documents in Firefox. This makes sense if you think about it, because HTML isn’t the same as XHTML. Since HTML isn’t as strict as XHTML, there exists the possiblity of inserting badly formed code into the document, and result wouldn’t be valid. From what I understand, this “problem” will be fixed in the 1.1 release of Firefox. Until then, I have an alternative. It may seem a little convoluted, but it really isn’t all that bad.

My approach revolves around using the DOM Core Methods. There is also another way, and that uses XSLT. I haven’t really looked into it, but I plan to, very soon. It could be faster.

Anyway, I realized that there was no way I could actually plug the XHTML code in directly into the document. I would have to parse it and create objects for each of the elements. But how do we parse the code? There really is no point writing our own parser, since it will be slow. Luckily, you can use the DOMParser object. This parser will let you parse an XML document. Since an XHTML document is essentially XML, you can use the DOMParser object to parse your code. The DOMParser object has three methods – parseFromBuffer, parseFromStream, and parseFromString. The one I used, is the last one. parseFromStream works like XMLHttpRequest, and allows you to read XML from a URI. I could have used that also, but parseFromString worked better for me.

The first thing you want to do, is create a DOMParser object. After that, you use parseFromString to parse your XML. parseFromString returns a Document object, which as you will see, can help us out a lot. So the code for parsing the XHTML looks like this:

var parser = new DOMParser();
var XMLdoc = parser.parseFromString("<root>" + myXHTML + "</root>");

It is not necessary to enclose your XHTML snippet with a root tag, but it will take care of the situation where your snippet doesn’t have a root element (so it would seem like it has more than one root element). In my case, I am inserting a snippet of XHTML code, and there is no root element, which is why I am enclosing the code with those tags.

I thought that once I had the Document object, I could simply figure out what the children of root are, and simply add them to the DOM by using appendChild. But that didn’t work out. This is due to the fact that XMLdoc is an XML Document, and not an HTML Document. Plugging it into the DOM directly won’t really help. What we have to do is figure out a way to transform the XML Document into an HTML Document. The sure-fire way to do that is to use XSLT. I poked around some code and realized that there was much I had to learn about XSLT before I could try to use it. My only other option was to do it through Javascript. This, as it turned out, wasn’t so bad. The Document object is essentially a tree, and all you’d have to do is “walk” the tree. While walking the tree, you can also create an object tree that you can later append to the main DOM.

I wrote a recursive function called walkTree that does exactly this. On a side-note, I am aware of the existence of the TreeWalker object, but I was too impatient to figure out how exactly it worked. It may actually prove to be faster, but who knows – maybe I will give it a try someday. Anyway, all those Data Structures and Algorithms classes that I had to take in College came to good use. My basic algorithm is this – you walk the tree, and every time you encounter a node, you create the appropriate XHTML element using createElementNS. First let’s look at the code to traverse the tree. Here is the basic skeleton that I use:

function walkTree(node)
{
         if(node.hasChildNodes())
         {
            node = node.firstChild;

            do
            {
                  alert("The node is " + node.nodeName +
                        " and its value is " + node.nodeValue
                       );

                  walkTree(node);
                  node = node.nextSibling;
            }
            while(node);
         }
}

Now we have to figure out how to use this skeleton to create elements and append them to the DOM. Like I mentioned before, you can create elements in XHTML using the createElementNS object. So you could do:

var element = createElementNS("http://www.w3.org/1999/xhtml", tagName);

The URI in createElementNS basically identifies the namespace we want to use. In this case, we want to use the XHTML namespace defined by the W3C. Now that we have created the element, we want to set its attributes. However, we don’t really know what the attributes are at runtime. But we can still access them using the attributes property of a node. The attributes property of a node is an array that contains all the attributes and their values. Now we have to figure out how to copy the attributes over to the element. There really is no easy way to do this. The only way I could figure out how to do this, was to construct Javascript code and use the eval() function. The reason for this is that every location in the attributes array is of type Node. The nodeName and nodeValue properties give us the attribute name and the attribute value respectively. So the code to set attributes would look like:

for(var i = 0; i < node.attributes.length; i++)
{
    var currAttribute = node.attributes[i];

    if(currAttribute.nodeName == "style")
    {
       applyStyle(element, currAttribute.nodeValue);
    }

    else if(currAttribute.nodeName == "class")
    {
       element.className = currAttribute.nodeValue;
    }

    else
    {
       eval("element." +
            node.attributes[j].nodeName +
            " = \"" +
            node.attributes[j].nodeValue +
            "\""
           );
    }
}

Pretty straightforward, but why do we have the if statements for “style” and “class”? Well, I’m sure you can see why you need the if statement for “class”. The attribute name in Javascript is different from the attribute name used in the XHTML code. But what’s that applyStyle function? Well, that function translates the CSS style into the Javascript format. So for example, if we had a style background-color:#ffffff;, the Javascript equivalent is obj.style.backgroundColor = “#ffffff”;. I wrote a simple function that performs this translation:

function applyStyle(obj, style)
{
         // Remove all whitespaces, and remove terminating ; if any
         style = new String(style).replace(/\s/g, "").replace(/;&#36;/, "");

         // Split into an array of attribute:value pairs
         var attributes = style.split(";");

         for(var i = 0; i < attributes.length; i++)
         {
             // Split the pair into the attribute and the value
             // Then translate the CSS style attribute into Javascript

             var attrvalue_pair = attributes[i].split(":");
             var attr = attrvalue_pair[0].replace(/-[a-z]/g, function($1)
                                                             {
                                                                      return new String($1).toUpperCase().replace(/-/g, "");
                                                             }
                                                 );

            // eval the constructed Javascript code

            eval("obj.style." + attr + " = \"" + attrvalue_pair[1] + "\"");
         }
}

Now we can put it all together:

function insertXHTML(myXHTML, myObject)
{
         var parser = new DOMParser();
         var XMLdoc = parser.parseFromString("<root>;" + myXHTML + "</root>", "text/xml");

         if(XMLdoc.documentElement.nodeName == "parserror")
         {
            alert("Your XML document has errors");
         }

         else
         {
            walkTree(XMLdoc.childNodes[0], myObject);
         }
}

function walkTree(node, parent)
{
         // Failing case for recursion. We don't want to continue 
         // if the node has no children.

         if(node.hasChildNodes())
         {
            // Set the node pointer to the first child of the current node
            // and start looping through all the children

            node = node.firstChild;

            do
            {
                  // We don't want any whitespace (line breaks, carriage returns, tabs or spaces)

                  if(!/^[\t\r\n ]+$/.test(node.data))
                  {
                     var element;

                     // Each node has a nodeType. The nodeType for a TextNode is 3. We want to handle
                     // Text Nodes separately from nodes that are tags

                     if(node.nodeType != 3)
                     {
                        // Create a new element using createElementNS as this is an XHTML file

                        element = document.createElementNS("http://www.w3.org/1999/xhtml", node.nodeName);

                        // Here, we manage the set the element's attributes by copying them from the node.
                        // Notice that we want to handle the style and class attributes separately. 
                        // The applyStyle function uses the CSS and creates the equivalent Javascript code
                        // for the style object of the current element. Look at the applyStyle function for
                        // more information

                        if(node.attributes)
                        {
                           for(var j = 0; j < node.attributes.length; j++)
                           {
                               var currAttribute = node.attributes[j];

                               if(currAttribute.nodeName == "style")
                               {
                                  applyStyle(element, currAttribute.nodeValue);
                               }

                               else if(currAttribute.nodeName == "class")
                               {
                                  element.className = currAttribute.nodeValue;
                               }

                               else
                               {
                                  // I guess this might be a hack, but I couldn't think of any other way to do it.
                                  // here we set any other attributes that the node may have. We construct Javascript
                                  // code to set the attributes and eval it. nodeName is the attribute name, and nodeValue
                                  // is the attribute value

                                  eval("element." + currAttribute.nodeName + " = \"" + currAttribute.nodeValue + "\"");
                               }
                           }
                        }
                     }

                     else
                     {
                        // If the element is a text node, we create a TextNode element

                        element = document.createTextNode(node.nodeValue);
                     }

                     // We make a recursive call to the function, to continue traversing the tree

                     walkTree(node, element);

                     // We append the element that we have created, to the parent element

                     parent.appendChild(element);
                  }

                  // Move onto the next sibling of the current node

                  node = node.nextSibling;
            }
            while(node);
         }
}

And there it is, folks. As easy as pie! I’ve found that it’s not that slow, especially if you’re parsing it just once. I’m using this same code for the Live! Preview, and it gets noticeably laggy when the code to be inserted is large. I guess if I was using XSLT, it wouldn’t be this slow. That’s going to be my next project! Feel free to use this code, and I hope it helps you out. Also, if you find ways to make it better/faster, or find bugs, or if you hate/love it, don’t hesitate to comment on it.

Update:

It was pointed out to me that there is a much simpler way of inserting XHTML into the document. You can use the importNode function, instead of walking the tree and manually copying the attributes. There doesn’t seem to be a speed advantage, but it is much simpler:

function insertXHTML(myXHTML, myObject)
{
         var parser = new DOMParser();
         var XMLdoc = parser.parseFromString("<div xmlns = "http://www.w3.org/1999/xhtml">" + comment + "</div>", "application/xhtml+xml");

         var root = XMLdoc.documentElement;

         for(i = 0; i < root.childNodes.length; i++)
         {
             myObject.appendChild(document.importNode(root.childNodes[i], true));
         }
}

I wish I had known about this function earlier – it would have saved me a whole lot of trouble!

References

All original content on these pages is fingerprinted and certified by Digiprove
%d bloggers like this: