Thoughts

Javascript + HTML Entities + Title Attribute = Headache

So last month, I was attending the fairly new Cleveland Web Standards Meet-Up. I was talking to Eric Wiley about the redesign I did for the Free Times, and Eric Meyer, who came for the first time, overheard. He says "new site, huh?" and pulls out his laptop.

It's possible my heart stopped working.

His critique of my work actually went fairly well for me. He commented on the fact that the ads came before the content, which I had already fixed on my local version, but hadn't uploaded yet (if someone had told me Eric Meyer would be there...). But then he noticed what I first assumed was one of those embarrassing bugs that crop up now and again where I just forgot something that, although simple to fix, was painfully obvious.

On the front page of the Free Times site, there is a simple javascript image rotater that loops through the current lead stories. The script changes the url of the link, and the src, alt, and title of the image. The problem was that in the tooltips that popped up, the HTML entities weren't converting to actual symbols. For example, what should have been "He's happy" turned out to say "He's happy." Oops.

I assumed it that I just forgot to do a conversion somewhere. It's happend before. However, the truth is much more sinister. The "title" attribute, when hard-coded in an html element, happily accepts html entities with no problem. The problem arises when javascript inserts them. I googled around for a while, but suprisingly couldn't find anything about the subject, so I hunkered down and figured it out myself.

The solution isn't very hard: when using PHP to print the text in question, use the rawurlencode() function, then use the javascript unescape() function when inserting the text. It seems silly, but works fine. I needed to use rawurlencode() and not urlencode() because urlencode() encodes spaces as '+' and javascript doesn't unescape them.

someElement.title = unescape("<?= rawurlencode($cover_story['title']) ?>");

So, the lesson learned: check everything. Especially if Eric Meyer will be going through your work.