<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>stchur-BLOG &#187; Mozilla-specific</title>
	<atom:link href="http://blog.stchur.com/category/mozilla-specific/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.stchur.com</link>
	<description>web / programming / javascript / css / html</description>
	<lastBuildDate>Sat, 16 Jan 2010 01:09:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Firefox 3 .pageX / .pageY bug</title>
		<link>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/</link>
		<comments>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 17:40:49 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Firefox Related]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[dispatchEvent]]></category>
		<category><![CDATA[Firefox 3]]></category>
		<category><![CDATA[pageX]]></category>
		<category><![CDATA[pageY]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/</guid>
		<description><![CDATA[	Firefox 3 has a bug.  It's somewhat obscure, and it probably doesn't affect you, but it did affect me.
	It also affected the Microsoft Virtual Earth MapControl, so if you use the VE MapControl for a mashup, your Firefox 3 users are going to be affected by this issue.
	The issue?  It has to do [...]]]></description>
			<content:encoded><![CDATA[	<p>Firefox 3 has a bug.  It's somewhat obscure, and it probably doesn't affect you, but it did affect me.</p>
	<p>It also affected the Microsoft <a href = "http://msdn.microsoft.com/en-us/virtualearth/default.aspx" title = "Microsoft Virtual Earth">Virtual Earth MapControl</a>, so if you use the VE MapControl for a mashup, your Firefox 3 users are going to be affected by this issue.</p>
	<p>The issue?  It has to do with a mouse event's <code>.pageX</code> and <code>.pageY</code> properties.  The values of those properties are supposed to report the "page" position of the mouse cursor, relative to the upper-left corner of the HTML page.  You can think of it as the absolute (x,y) of the mouse cursor.</p>
	<p>The nice thing about <code>.pageX/Y</code> is that serves as an easy way to get the mouse position, <em>regardless</em> of how much (or even if) the browser window is scrolled.</p>
	<p>Contrast <code>.pageX/Y</code> with <code>.clientX/Y</code>:  the latter reports (x,y) coordinates relative to the upper-left corner of the browser window, so these values <em>will</em> be affected by browser scroll position.</p>
	<p>Anyway, at this point, you're probably thinking that I'm going to tell you that Firefox 3 reports the wrong values for <code>.pageX/Y</code>, and that that's the bug.  It's not that simple though (again, I admit this is a somewhat obscure bug).</p>
	<p><em>Most</em> of the time, Firefox 3 reports the right values for <code>.pageX/Y</code>, but there is one case in which it doesn't.</p>
	<h3>Manually Dispatching Events in Javascript</h3>
	<p>A while back, I wrote a post about <a href = "http://blog.stchur.com/2007/11/16/re-routing-events-in-javscript/" title = "Re-routing Events in Javascript">Re-routing events in Javascript</a>.  In it, I explain how to create an event and initialize it with <code>myEvt.initMouseEvents(..)</code> (which takes a <a href = "http://developer.mozilla.org/en/docs/DOM:event.initMouseEvent" title = "Mozilla Developer Center (initMouseEvent)">boat-load</a> of parameters).</p>
	<p>Of all those parameters sent into <code>.initMouseEvents(..)</code>, 4 are of particular interest: <code>.screenX</code>, <code>.screenY</code>, <code>.clientX</code>, and <code>.clientY</code>.</p>
	<p>Notice that <code>.pageX</code> and <code>.pageY</code> are not in the list.  You don't get the ability to pass in <code>.pageX/Y</code> when manually creating/dispatching an event in Javascipt.  Presumably, the values for these properties are computed based on <code>.clientX/Y</code> and the browser's scroll position.</p>
	<p>So for example, if you initialize a MouseEvent with <code>.clientX</code> = 200 and <code>.clientY</code> = 300, and if the browser is scrolled 50 x 75, then your event's <code>.pageX</code> and <code>.pageY</code> values will be 250 and 375 respectively.</p>
	<p>Oops!  I mean, that's what the values <em>should</em> be.</p>
	<h3>The Bug</h3>
	<p>Firefox 2 actually gets it right, but Firefox 3 doesn't.</p>
	<p>When you're manually dispatching a MouseEvent in Firefox 3, the <code>.pageX/Y</code> property values will <em>always</em> be equal to the <code>.clientX/Y</code> values, <em>regardless</em> of browser scroll position.</p>
	<p>As I previously mentioned, this affects the VE MapControl, so it's easy to see the issue in action.  Just use Firefox 3 and point your browser to <a href = "http://maps.live.com" title = "Microsoft Live Search Maps">http://maps.live.com</a>.  Now make your browser window small enough to cause scroll bars to appear.  Scroll the browser window by some amount (doesn't matter how much) and try panning the map.  You should see the map "jump" during the initial pan.  The amount it "jumps" is going to be equal to the amount by which the browser window is scrolled.</p>
	<h3>The Fix</h3>
	<p>Microsoft has a work-around for this issue that is going to be released with the next version of Virtual Earth, but if you're a mashup dev using the VE MapControl, I've got a solution that you can use right now, and it goes like this:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> mouseEvt;<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> document.<span class="me1">createEvent</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt = document.<span class="me1">createEvent</span><span class="br0">&#40;</span><span class="st0">'MouseEvents'</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>mouseEvt &amp;&amp; mouseEvt.__proto__ &amp;&amp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#40;</span><span class="st0">'pageX'</span>, <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">clientX</span> + window.<span class="me1">pageXOffset</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; mouseEvt.__proto__.__defineGetter__<span class="br0">&#40;</span><span class="st0">'pageY'</span>, <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">clientY</span> + window.<span class="me1">pageYOffset</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
	<p>Just include the preceding code snippet anywhere in your HTML page.  The code is pretty straight-forward and just relies on the fact that Firefox (and others) have the ability to define getters through the use of <code>.__defineGetter__(..)</code>.</p>
	<p>The <code>.pageX/Y</code> properties are read only, but it turns out that the browser will let you redefine these getters, thereby overriding their return logic.  Since the <code>.clientX/Y</code> properties appear to always report the correct value, all we have to do redefine the <code>.pageX/Y</code> getters to use a combination of <code>.clientX/Y</code> + <code>.pageX/YOffset</code>.</p>
	<p>In other words, we've redefined <code>.pageX/Y</code> to always return the position of the event (in our case, the mouse cursor since we're dealing with MouseEvents), relative to the upper-left corner of the browser window + the scrolled position of the browser -- what it should have been all along!</p>
	<p>This code doesn't hurt IE, as it won't execute in that browser, and it doesn't hurt Firefox 2 or other browsers that understand the code either, because the logic we've defined for the getters is going to be essentially the same as what the browser would have done natively anyway.</p>
	<p>I'd like to file a bug to Mozilla on this issue, but I haven't a clue as to how one goes about doing that.  If anyone knows (or wants to do it for me), feel free to speak up!</p>
	<p>Enjoy the fix!</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/07/03/firefox-3-pagex-pagey-bug/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>CSS Word-wrap: break word; (revisited)</title>
		<link>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/</link>
		<comments>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 00:16:30 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Advanced Javascript]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Firefox Related]]></category>
		<category><![CDATA[MiniPosts]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/</guid>
		<description><![CDATA[HedgerWow is a great blog.  If you've never checked it out, you definitely should.

I just noticed the other day that his latest post gives some props to my Emulating CSS word-wrap for Mozilla/Firefox blog post, but his version adds some much needed cross-browser support for browsers I neglected.

Nice One, HedgerWow!]]></description>
			<content:encoded><![CDATA[<p><a href = "http://www.hedgerwow.com" title = "Keep It Simple, Stupid">HedgerWow</a> is a great blog.  If you've never checked it out, you definitely should.</p>

<p>I just noticed the other day that his latest post gives some props to my <a href = "http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Emulating CSS word-wrap for Mozilla/Firefox">Emulating CSS word-wrap for Mozilla/Firefox</a> blog post, but <a href = "http://www.hedgerwow.com/360/dhtml/css-word-break.html" title = "Cross Browser Word Breaker">his version</a> adds some much needed cross-browser support for browsers I neglected.</p>

<p><a href = "http://www.hedgerwow.com/360/dhtml/css-word-break.html" title = "Cross Browser Word Breaker">Nice One</a>, HedgerWow!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/06/29/css-word-wrap-break-word-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox 3</title>
		<link>http://blog.stchur.com/2008/06/19/firefox-3/</link>
		<comments>http://blog.stchur.com/2008/06/19/firefox-3/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 14:45:50 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Firefox Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[MiniPosts]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Web-related]]></category>

		<guid isPermaLink="false">http://blog.stchur.com/2008/06/19/firefox-3/</guid>
		<description><![CDATA[Well unless you've been living under a rock, you know that Firefox 3 was released on Tuesday.  This is a big deal for me. When other browser makers release a new version, it's like eh... ok, that's cool (I guess).  But when Mozilla releases a new Firefox, I've got a brand new shiny [...]]]></description>
			<content:encoded><![CDATA[<p>Well unless you've been living under a rock, you know that <a href = "http://www.getfirefox.com" Title = "Firefox">Firefox 3</a> was released on Tuesday.  This is a big deal for me. When other browser makers release a new version, it's like eh... ok, that's cool (I guess).  But when Mozilla releases a new Firefox, I've got a brand new shiny app to get me through my day to day web browsing.</p>

<p>Besides the new theme (on Windows) being a little bland, FF3 does <em>not</em> disappoint!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2008/06/19/firefox-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serializing Objects in Javascript</title>
		<link>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/</link>
		<comments>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/#comments</comments>
		<pubDate>Fri, 06 Apr 2007 06:12:06 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Beating IE into submission]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/04/06/serializing-objects-in-javascript/</guid>
		<description><![CDATA[	Recently, in a personal project I'm working on, I came across a need to be able to represent any Javascript object as a string.  This isn't a problem since just about every object in Javascript can be represented with JSON (Javascript Object Notation).  Every modern browser can parse JSON for you easily enough [...]]]></description>
			<content:encoded><![CDATA[	<p>Recently, in a personal project I'm working on, I came across a need to be able to represent any Javascript object as a string.  This isn't a problem since just about every object in Javascript can be represented with <abbr title = "Javascript Object Notation">JSON</abbr> (Javascript Object Notation).  Every modern browser can parse <abbr>JSON</abbr> for you easily enough through <code>eval(..)</code>, and Gecko-based browsers even have the ability to reverse the process ("uneval" if you will) and give you back a string representation of an object through a call to <code>.toSource()</code>.</p>
	<p>If you need this ability in any other browser though, you're gonna have to write it yourself.  I needed this ability, so I wrote it (and posted it here for your enjoyment!)</p>
	<p><span id="more-41"></span></p>
	<h3>Gecko-based browsers, .toSource():</h3>
	<p>Gecko-based browsers provide a handy function: <code>.toSource()</code> that you can call on any object in your Javascript code to get back a JSON-like representation of that object.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> Cat<span class="br0">&#40;</span><span class="kw3">name</span>, age<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="kw3">Name</span> = <span class="kw3">name</span>;<br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">Age</span> = age;<br />
&nbsp; &nbsp;<span class="kw1">this</span>.<span class="me1">Speak</span> = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'Meow!'</span><span class="br0">&#41;</span>; <span class="br0">&#125;</span>;<br />
<span class="br0">&#125;</span></p>
	<p><span class="kw2">var</span> garfield = <span class="kw2">new</span> Cat<span class="br0">&#40;</span><span class="st0">'Garfield'</span>, <span class="nu0">5</span><span class="br0">&#41;</span>;<br />
<span class="kw3">alert</span><span class="br0">&#40;</span>garfield.<span class="me1">toSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
	<p><span class="coMULTI">/* garfield.toSource() yields:<br />
({Name:&quot;Garfield&quot;, Age:5, Speak:(function () {alert(&quot;Meow!&quot;);})})<br />
*/</span><br />
&nbsp;</div>
	<p>Pretty simple right?  You have an object; you want a string.  Just invoke the object's <code>.toSource()</code> function.</p>
	<h3>Serializing objects in other browsers:</h3>
	<p>Serializing an object manually (as is required by non Gecko-based browsers) requires a bit of <a href = "http://en.wikipedia.org/wiki/Recursion">recursion</a>.  Simple types like integers, booleans, and even functions are trivial to represent as strings.  Objects though, are more complicated because they can contain simple types <em>or</em> custom objects (which would need to be serialized themselves).  Those "inner" objects could in turn, contain <em>more</em> custom objects, which would <em>also</em> need to be serialized, and this pattern could (theoretically) go on forever.</p>
	<p>In practice of course, this pattern <em>will</em> (had better) come to an end.  And we can leverage that fact to write a recursive function that will return a string representation (in <abbr>JSON</sbbr> format) of a given object.</p>
	<h3>The serialize(..) function:</h3>
	<p>First the code, then the explanation.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> serialize<span class="br0">&#40;</span>_obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// Let Gecko browsers do this the easy way</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _obj.<span class="me1">toSource</span> !== <span class="st0">'undefined'</span> &amp;&amp; <span class="kw1">typeof</span> _obj.<span class="me1">callee</span> === <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _obj.<span class="me1">toSource</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="co1">// Other browsers must do it the hard way</span><br />
&nbsp; &nbsp;<span class="kw1">switch</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _obj<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// numbers, booleans, and functions are trivial:</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// just return the object itself since its default .toString()</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// gives us exactly what we want</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'number'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'boolean'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'function'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> _obj;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="co1">// for JSON format, strings need to be wrapped in quotes</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'string'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'<span class="es0">\'</span>'</span> + _obj + <span class="st0">'<span class="es0">\'</span>'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">case</span> <span class="st0">'object'</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> str;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_obj.<span class="me1">constructor</span> === Array || <span class="kw1">typeof</span> _obj.<span class="me1">callee</span> !== <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = <span class="st0">'['</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> i, len = _obj.<span class="me1">length</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>i = <span class="nu0">0</span>; i &lt; len<span class="nu0">-1</span>; i++<span class="br0">&#41;</span> <span class="br0">&#123;</span> str += serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">','</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str += serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">']'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = <span class="st0">'{'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> key;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">for</span> <span class="br0">&#40;</span>key <span class="kw1">in</span> _obj<span class="br0">&#41;</span> <span class="br0">&#123;</span> str += key + <span class="st0">':'</span> + serialize<span class="br0">&#40;</span>_obj<span class="br0">&#91;</span>key<span class="br0">&#93;</span><span class="br0">&#41;</span> + <span class="st0">','</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;str = str.<span class="me1">replace</span><span class="br0">&#40;</span><span class="re0">/\,$/</span>, <span class="st0">''</span><span class="br0">&#41;</span> + <span class="st0">'}'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> str;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">default</span>:<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">return</span> <span class="st0">'UNKNOWN'</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">break</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
	<p>Explaining a recursive function can be difficult, but I'll give it shot:</p>
	<p>The function accepts just one parameter: the object (<code>_obj</code>) to be serialized.  If you'll remember, I mentioned previously that simple types (string, boolean, number, etc...) were trivial because they all have an obvious string representation already.  Complex types though, are more difficult because they can be made up of additional complex types, which in turn could be made up of additional complex types (and so on).</p>
	<p>Of course, this pattern will eventually end; ultimately, everything is made up of simple types that have a string representation.  The trick is figuring out how to traverse through this maze of "types within types."  Recursion (simply stated: a function that calls itself) is perhaps the easiest way to solve this "types within types" problem.</p>
	<p>Recursive functions always have a termination case -- something which causes the function to <em>stop</em> calling itself.  Otherwise, the function would go into an infinite loop.  In our function, there are actually four different cases in which the <code>serialize(..)</code> doesn't need to call itself:</p>
	<ol>
	<li>typeof _obj is a number</li>
	<li>typeof _obj is a boolean</li>
	<li>typeof _obj is a function</li>
	<li>typeof _obj is a string</li>
	</ol>
	<p>If any of the above four conditions are met, returning a string representation is trivial, so we simply do it.</p>
	<div class = "note">
You'll notice that strings are treated separately from the other 3 types.  You'd think strings would be the most trivial case, but actually, there is one thing we must do before returning the "string representation" of <code>_obj</code> when it is of type string:  wrap it in quotes.  We need to do this, because JSON expects it, and if we ever want to be able to <code>eval(..)</code> the result of a <code>serialize(..)</code> call, we'll need these quotes.
</div>
	<p>The only other case to deal with is when <code>_obj</code> is of type <code>object</code>.  Within this case though, there are two "sub-cases" we need to deal with.  The first is when <code>_obj</code> is an <code>Array</code>, or when it has a <code>.callee</code> property (more on that later).  The second is well... anything else.</p>
	<h3>Basic Object Types</h3>
	<p>Your every-day, run-of-the-mill, object in Javascript can be represented as JSON with:</p>
	<p><code>{ key1: val1, key2: val2, ... }</code></p>
	<p>Where the keys are strings and the vals can be any simple type, or some custom object you've dreamed up.  The logic I've used is to simply loop through a given object's keys and build a string of comma delimited, <em>serialized</em> key/value pairs that are wrapped in { and }.</p>
	<p>Notice I said <em>serialized</em> key/value pairs.  Here, our function is calling itself as it builds the object representation.  This ensures that any objects within the object being serialized will <em>also</em> be serialized.  If we didn't do this, we'd end up with a lot of strings that looked (something) like this:</p>
	<p><code>{ key1: [object Object], key2: [object Object], etc... }</code></p>
	<p>And that's clearly not what we want.  We want those inner objects to be serialized as well, and that's what the recursive nature of our function will take care of for us.</p>
	<h3>Arrays</h3>
	<p>When <code>_obj</code> happens to be, not just any object, but more specifically, an <code>Array</code>, we have a better way of representing that as a string:</p>
	<p><code>[ val1, val2, val3, ... ]</code></p>
	<p>The logic I used here is to simply iterate through the array building a comma delimited list of <em>serialized</em> values, wrapped in [ and ].  Arrays in Javascript already have a <code>.toString()</code> function, but we can't use it here; if the Array contains objects, then the result of the Array 's <code>.toString()</code> could end up something like:</p>
	<p><code> [ [object Object], [object Object], etc... ]</code></p>
	<p>Again, not what we want, so we need to make sure we recursively serialize all of the elements in the array.</p>
	<h3>Arguments (the .callee "gotcha")</h3>
	<p>There's one bit of code I haven't discussed yet and it deals with the (possible) <code>.callee</code> property of the passed in <code>_obj</code>.  It turns out that <code>.toSource()</code> (native function used by Gecko-based browsers) doesn't do anything very useful when called on an <code>arguments</code> object.</p>
	<p>The <code>arguments</code> object is an array-like (but not an Array) object that is automatically available within the scope of every function.  Unfortunately, no matter what is contained within that <code>arguments</code> object, calling <code>.toSource()</code> on it will always return <code>"({})"</code></p>
	<p>In order to be able to serialize an <code>arguments</code> object then, we need some way to detect it and then treat it like an array.  The <code>.callee</code> property is a good choice because <code>arguments</code> objects have it, but other objects (to the best of my knowledge) do not.</p>
	<p>In the case of the <code>serialize(..)</code> function, I decided to use the native <code>.toSource()</code> function whenever it was available, <em>unless</em> the object were an <code>arguments</code> object, in which case, I send Gecko-based browsers down the same path as all other browsers for serialization.</p>
	<p>Finally, just for good measure, I've added a default case which returns the string <code>UNKNOWN</code> to handle a situation where no other cases applied.  Of course, we probably don't <em>want</em> <code> UNKNOWN</code> showing up in the our serialized strings, but it probably won't do much (immediate) harm if it ever does show up, <em>and</em> its presence would be a helpful indicator that there is some case not being met (that probably needs to be).</p>
	<h3>Conclusion:</h3>
	<p>What would you ever use a function like this for?  Well, In my case, I wanted to use a Javascript object as the key for a hash, but if I tried to do that, Javascript would just represent all of my (different) objects as the same string: <code>[object Object]</code>, which wouldn't do me any good.  By serializing the object, I can then use that serialized representation as a key in the hash.</p>
	<p>It's worked well for my need so far, but I haven't tested it a great deal.  If you find any bugs or short-comings, please let me know.</p>
	<p>As always, comments are welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/04/06/serializing-objects-in-javascript/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Mouseenter and mouseleave events for Firefox (and other non-IE browsers)</title>
		<link>http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/</link>
		<comments>http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/#comments</comments>
		<pubDate>Thu, 15 Mar 2007 08:08:33 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Mozilla-specific]]></category>
		<category><![CDATA[Useful Functions]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/</guid>
		<description><![CDATA[	Generally I favor Firefox and other W3C browsers over IE, and I think most people know that about me.  Still, I like to think that I'm a fair person, and that means giving credit where credit is due.  And sometimes, IE deserves credit where other browsers fall short.
	Such is the case with two [...]]]></description>
			<content:encoded><![CDATA[	<p>Generally I favor Firefox and other W3C browsers over IE, and I think most people know that about me.  Still, I like to think that I'm a fair person, and that means giving credit where credit is due.  And sometimes, IE deserves credit where other browsers fall short.</p>
	<p>Such is the case with two non-standard (but rather convenient) events that IE exposes: <code>mouseenter</code> and <code>mouseleave</code>.</p>
	<p>The <code>mouseenter</code> and <code>mouseleave</code> events are similar to the more familiar <code>mouseover/mouseout</code> events, but with one important difference:</p>
	<p>The <code>mouseenter</code> and <code>mouseleave</code> events don't bubble.</p>
	<p>Now you might think then, that duplicating this effect is just a matter of stopping event propagation in non-IE browsers, but it's actually more complicated than that.</p>
	<p>Read on to learn more.</p>
	<p><span id="more-32"></span></p>
	<p>To help illustrate more clearly what <code>mouseenter/mouseleave</code> allow you to do, consider the following:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="sc3"><span class="re1">&lt;ul</span> id = <span class="st0">&quot;theList&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;li<span class="re2">&gt;</span></span></span>List Item One<span class="sc3"><span class="re1">&lt;/li<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;li<span class="re2">&gt;</span></span></span>List Item Two<span class="sc3"><span class="re1">&lt;/li<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;li<span class="re2">&gt;</span></span></span>List Item Three<span class="sc3"><span class="re1">&lt;/li<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;li<span class="re2">&gt;</span></span></span>List Item Four<span class="sc3"><span class="re1">&lt;/li<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/ul<span class="re2">&gt;</span></span></span></p>
	<p><span class="sc3"><span class="re1">&lt;script</span> type = <span class="st0">&quot;text/javascript&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp;document.getElementById('theList').attachEvent('onmouseenter', myFn);<br />
&nbsp; &nbsp;document.getElementById('theList').attachEvent('onmouseleave', myFn);</p>
	<p>&nbsp; &nbsp;function myFn(e)<br />
&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;alert(e.type + ': ' + e.srcElement.id);<br />
&nbsp; &nbsp;}<br />
<span class="sc3"><span class="re1">&lt;/script<span class="re2">&gt;</span></span></span></div>
	<p>In the preceding example, the function, <code>myFn()</code>, will execute each time you move the mouse cursor into <code>#theList</code>, but it <em>won't</em> execute when you move the mouse cursor in or out of the child list items that belong to <code>#theList</code> (something that it <em>would</em> do had we used the <code>mouseover/mouseout</code> events instead).</p>
	<p>As I mentioned previously, the major different between <code>mouseenter/mouseleave</code> events and <code>mouseover/mouseout</code> events is that the former don't bubble.  And this is really what makes the events useful.  In our example, the child list items of <code>#theList</code> still receive the <code>mouseenter/mouseleave</code> events (even if you aren't listening for them) but the events won't bubble up to their parent <code>&lt;ul&gt;</code> element.</p>
	<p>Of course you <em>could</em> achieve this same effect in non-IE browsers by stopping event propagation, but <em>not</em> by stopping it on the <code>#theList</code> (which is the element to which you'd be wiring up the <code>mouseover/mouseout</code> events).</p>
	<p>No, you'd have to utilize <code>.addEventListener(..)</code> for each child element of <code>#theList</code>, hooking up functions to the <code>mouseover/mouseout</code> events that would take care of stopping the events from propagating (in this case bubbling) up to the parent element, and <em>that</em> would be a royal pain (not to mention that you might <em>want</em> the <code>mouseover/mouseout</code> events to bubble up for some (unrelated) reason).</p>
	<p>A better approach would be to write a cross-browser <code>addEvent(..)</code> function that knows how to treat  'mouseenter' and 'mouseleave' as valid events.</p>
	<p>Here's the code to make it happen, with the explanation to follow.</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">function</span> addEvent<span class="br0">&#40;</span>_elem, _evtName, _fn, _useCapture<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _elem.<span class="me1">addEventListener</span> != <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_evtName === <span class="st0">'mouseenter'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> _elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'mouseover'</span>, mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>, _useCapture<span class="br0">&#41;</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span>_evtName === <span class="st0">'mouseleave'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> _elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'mouseout'</span>, mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span>, _useCapture<span class="br0">&#41;</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> _elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span>_evtName, _fn, _useCapture<span class="br0">&#41;</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> _elem.<span class="me1">attachEvent</span> != <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;_elem.<span class="me1">attachEvent</span><span class="br0">&#40;</span><span class="st0">'on'</span> + _evtName, _fn<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp;<span class="kw1">else</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;_elem<span class="br0">&#91;</span><span class="st0">'on'</span> + _evtName<span class="br0">&#93;</span> = _fn;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></p>
	<p><span class="kw2">function</span> mouseEnter<span class="br0">&#40;</span>_fn<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">return</span> <span class="kw2">function</span><span class="br0">&#40;</span>_evt<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw2">var</span> relTarget = _evt.<span class="me1">relatedTarget</span>;<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">this</span> === relTarget || isAChildOf<span class="br0">&#40;</span><span class="kw1">this</span>, relTarget<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<span class="br0">&#123;</span> <span class="kw1">return</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;_fn.<span class="me1">call</span><span class="br0">&#40;</span><span class="kw1">this</span>, _evt<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span>;</p>
	<p><span class="kw2">function</span> isAChildOf<span class="br0">&#40;</span>_parent, _child<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>_parent === _child<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="kw2">false</span>; <span class="br0">&#125;</span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="kw1">while</span> <span class="br0">&#40;</span>_child &amp;&amp; _child !== _parent<span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span> _child = _child.<span class="me1">parentNode</span>; <span class="br0">&#125;</span></p>
	<p>&nbsp; &nbsp;<span class="kw1">return</span> _child === _parent;<br />
<span class="br0">&#125;</span></div>
	<p>Several things to notice here:</p>
	<p>First, if the browser supports <code>.addEventListener(..)</code> we need to do a little extra work to support <code>mouseenter/mouseleave</code>.</p>
	<p><em>But</em> (and I can't stress this enough), this concept is absolutely flawed!  We're <em>assuming</em> that if the browser supports <code>.addEventListener(..)</code> then it must <em>not</em> support <code>mouseenter/mouseleave</code>.</p>
	<p>While this happens to be true at present (to the best of my knowledge) it's unwise to assume that this will always be the case.  The problem is, there is no (highly reliable) way to determine whether or not a browser supports a particular event (at least not that I know of).  I'm okay with this approach for now, only because we're writing the code in such a way, that even if a browser <em>did</em> support <code>mouseenter/mouseleave</code>, our custom implementation of it shouldn't cause any major problems.</p>
	<p>Second, you'll notice that when we wire up the event handler, we don't directly use the <code>_fn</code> variable that the user passed in.  Instead we use it indirectly by proxying it through the <code>mouseEnter(..)</code> function.</p>
	<p>Third, note that we call the same <code>mouseEnter(..)</code> function regardless of whether we're dealing withing with <code>mouseenter</code> or <code>mouseleave</code>.  Remember though, that <code>mouseenter/mouseleave</code> are just "psuedo" events (if you will).  The actually events we're wiring up are <code>mouseover</code> and <code>mouseout</code> which, in our function, map to <code>mouseenter</code> and <code>mouseleave</code> respectively.  This allows us to use one function to handle both events.</p>
	<p>Fourth, the <code>mouseEnter(..)</code> function <em>returns</em> a function.  I talked about this a while back in post about closures, so I won't go into a lot of detail here, but I did feel that it was wort pointing out in case you hadn't noticed.</p>
	<h3>The mouseEnter(..) function:</h3>
	<p>The <code>mouseEnter(..)</code> is where half the magic happens (the other half being in the <code>isAChildOf(..)</code> function (which I'll get to shortly).  The <code>.mouseEnter(..)</code> function basically just "intercepts" <code>mouseover</code> or <code>mouseout</code> events and "decides" whether or not to dispatch them (by invoking <code>_fn</code> through the use of the <code>.call(..)</code> function).</p>
	<p>It does this by obtaining a reference to the related target.  In the case of <code>mouseover</code>, the related target would be the element being moused <em>from</em>, and in the case of <code>mouseout</code>, the related target would be the element being moused <em>to</em>.</p>
	<p>Once we know the related target, all we need to do before calling the actual function is make sure of two things:</p>
	<ol>
	<li>That the related target is <em>not</em> child of the element to which we wired up the event (that would be the <code>this</code> element).</li>
	<li>That the related target is not, itself, the element to which we wired up the event</li>
	</ol>
	<p>Number two in the above list is easy.  We accomplish by just checking: <code>if (this === relTarget)</code>.  Number one is slightly more difficult, so for that one, we call on the help of another function: <code>isAChildOf(..)</code>.</p>
	<h3>The isAChildOf(..) function:</h3>
	<p>As its name imples, <code>isAChildOf(..)</code> tells you if one element is a child element of another.  Simply pass in the (suspected) parent element as the first parameter, and the (possible) child element as the second parameter, and the function will return <code>true</code> or <code>false</code> accordingly.</p>
	<div class = "note">
Some of you might be wondering why I didn't just leverage <code>.prototype</code> to add a <code>.contains(..)</code> function to the native <code>HTMLElement</code>.  I chose not to do this, because I think I remember reading somewhere that Safari does not expose the prototype of <code>HTMLElement</code> (though I hear there is a way around this).  However, not being a Mac user, the best I could do was test in Konqueror, and while it worked in that browser, that wasn't really enough to make me feel good about this approach.</div>
	<p>The <code>isAChildOf(..)</code> function is pretty simple.  It works by repeatedly setting the <code>_child</code> variable to its <code>.parentNode</code>, thus cycling it up the chain.  Eventually, the <code>_child</code> will be either "false-like" (probably null) or it will be equal to the <code>_parent</code>.  In either case, we break out of the while loop.</p>
	<p>Once out of the while loop, we <code>return (_child === _parent)</code>.  This works because any element that was originally a child of the <code>_parent</code> element, would eventually <em>be</em> the parent element (as it gets cycled up the chain).  Otherwise, it must not have been a child in the first place. Cool!</p>
	<p>So if the related target itself, is either the element to which the event was wired up, or if the related target is a child of the of the element to which the event was wired up, we <em>don't</em> want to dispatch the event.  Programmatically, we simply <code>return</code> (prematurely) if either one of these conditions turns out to be true.  Otherwise, we can go ahead and call the desired function, and we should end up with a very nice <code>mouseenter/mouseleave</code> simulation.</p>
	<h3>Final thoughts:</h3>
	<p>There are a few important things to point out before I close with this entry:</p>
	<p>First, the <code>addEvent(..)</code> function we wrote here would be a lot better if we merged it with the <code>xb.addEventListener(..)</code> function that was described in the blog entry <a href = "http://blog.stchur.com/2006/10/12/fixing-ies-attachevent-failures/">Fixing IE's .attachEvent(..) Failures</a>.  For the sake of brevity though, I chose not to do that here.</p>
	<p>Second, our simulation of <code>mouseenter/mouseleave</code> does fall short with regards to the event object's <code>.type</code> property.  Since what we're really using under the hood is <code>mouseover/mouseout</code>, any request for <code>_evt.type</code> is going to return either 'mouseover' or 'mouseout', but never 'mouseenter' or 'mouseleave' <img src='http://blog.stchur.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
	<p>Finally, there is one problem I haven't yet mentioned with our implementation here, and unfortunately, it's a <strong>doozy!</strong></p>
	<p>Since the <code>_fn</code> passed into <code>addEvent(..)</code> is not called directly, but rather, proxy'd through the <code>MouseEnter(..)</code> function, we're unable to remove any event listener that's been wired up as 'mouseenter' or 'mouseleave'... ever!</p>
	<p>And boy does that suck!  This is a result of the fact that <code>MouseEnter(..)</code> returns an anonymous function, and, as discussed in a <a href = "http://ecmascript.stchur.com/2007/01/02/lambda-function-quick-tips/">previous post</a>, you can't detach anonymous functions.</p>
	<p>It's worth noting that this is not a browser-specific problem.  All browsers will handle this the same way, even IE (had we been using the closure technique for that browser).</p>
	<p>I do have a work around, and it's eerily similar to the event hash concept used in the <code>xb.addEventListener(..)</code> function for the IE branch of code.  I'm not thrilled with the solution, and I'm convinced there is a cleaner way.  So my intention is to hold off until I figure out what that is.</p>
	<p>In the meantime, if anyone out there has an elegant solution that would allow us to detach the functions wired up with 'mouseenter' or 'mouseleave', please feel free to send your comments.  I'd be really interested to see how others might attack this problem.</p>
	<h3>Live demo:</h3>
	<p>To see a live demo, visit <a href = "http://ecmascript.stchur.com/blogcode/mouseenter_mouseleave/">this page</a>.</p>
	<p>Comments appreciated!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Word-wrap for Mozilla (take 2)</title>
		<link>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/</link>
		<comments>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 07:18:16 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Mozilla-specific]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/03/01/word-wrap-for-mozilla-take-2/</guid>
		<description><![CDATA[	
This blog entry is a follow-up to my last blog entry, Emulating CSS word-wrap for Mozilla/Firefox.  In this entry, I work under the assumption that the reader has read the original post.   If you haven't, I highly encourage you to do so before reading this post, as the contents of this one [...]]]></description>
			<content:encoded><![CDATA[	<div class = "note">
This blog entry is a follow-up to my last blog entry, <a href = "http://ecmascript.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/">Emulating CSS word-wrap for Mozilla/Firefox</a>.  In this entry, I work under the assumption that the reader has read the original post.   If you haven't, I highly encourage you to do so before reading this post, as the contents of this one will be much more relevant if you do.
</div>
	<p>In my last entry, I discussed how one might achieve something similar to the CSS style rule: "word-wrap: break-word;" in Mozilla-based browsers.</p>
	<p>The technique I used to accomplish this centered around using a Mozilla binding to automatically insert an invisible unicode hyphen between the characters of a string contained within any element whose class was set to "wordwrap."  With this invisible character in place, Mozilla will happily wrap a long string whenever the element's content overflows its container.</p>
	<p>There was a catch with my approach though.  I wanted to be able to modify, not only any inner text of a "wordwrap" element, but I also needed the logic of my binding to leave in tact, any HTML that may have existed inside the given element.</p>
	<p>The logic I ended up using was to insert the unicode character between <em>each and every</em> character in the element's <code>.innerHTML</code> (including any HTML tags).  Obviously though, this would "mangle" the HTML tags thereby making them useless.  So, I then added a bit more logic which utilized regular expressions plus a callback function in a <code>.replace(..)</code> call to "unmangle" the HTML I screwed up in the first place.</p>
	<p>This worked, but as alert reader, Rich Birkby, kindly pointed out, there is an easier way.  A way that, as it turns out, is quite simple to implement and doesn't require "mangling" any of the HTML tags within the "wordwrap" element.</p>
	<p>Read on to learn more.</p>
	<p><span id="more-30"></span></p>
	<p>This superior technique (IMO) that Rich informed me of was the TreeWalker.  A TreeWalker is a an object that you can create in Mozilla-based browsers that allows you to navigate the document tree.</p>
	<p>The <code>document.createTreeWalker(..)</code> function takes 4 parameters which allow you to specify some specifics about exactly how the walker should "do its walking" (if you will).  Each parameter is explained in more detail below:</p>
	<ol>
	<li><strong>rootNode</strong>: The node in the document that is to serve as the root node for this tree walker.</li>
	<li><strong>whatToShow</strong>: An integer constant that specifies one of several built in filters for selecting nodes to be included in the tree.  Listed below are the acceptable values for this parameter:
	<ul>
	<li>NodeFilter.SHOW_ALL</li>
	<li>NodeFilter.SHOW_CDATA_SECTION</li>
	<li>NodeFilter.SHOW_DOCUMENT</li>
	<li>NodeFilter.SHOW_DOCUMENT_TYPE</li>
	<li>NodeFilter.SHOW_ENTITY</li>
	<li>NodeFilter.SHOW_NOTATION</li>
	<li>NodeFilter.SHOW_TEXT</li>
	<li>NodeFilter.SHOW_ATTRIBUTE</li>
	<li>NodeFilter.SHOW_COMMENT</li>
	<li>NodeFilter.SHOW_DOCUMENT_FRAGMENT</li>
	<li>NodeFilter.SHOW_ELEMENT</li>
	<li>NodeFilter.SHOW_ENTITY_REFERENCE</li>
	<li>NodeFilter.SHOW_PROCESSING_INSTRUCTION</li>
	</ul>
</li>
	<li><strong>filterFunction</strong>: This parameter can be a reference to a filter function.  Its purpose is to allow you to filter nodes even further than what the <code>whatToShow</code> parameter can provide.  If you have no need for this parameter, simply pass in <code>null</code>.  However, if you specify a function, it must accept a single node and return an integer value based on one of the following constants:
	<ul>
	<li>NodeFilter.FILTER_ACCEPT</li>
	<li>NodeFilter.FILTER_REJECT</li>
	<li>NodeFilter.FILTER_SKIP</li>
	</ul>
</li>
	<li><strong>entityRefExpansion</strong>: A boolean value that determines whether or not the content of the entity reference nodes should be treated as hierarchial nodes.  In most cases, this value will probably be <code>false</code>.</li>
	</ol>
	<h3>Updating the original code to use the TreeWalker:</h3</p>
	<p>For our purposes (emulating the word-wrap CSS property) we won't need to get very fancy with the TreeWalker at all.  All we really need to do is traverse the tree of the element that's been bound by our Mozilla Binding.  We'll make use of the SHOW_TEXT filter to ensure that we visit only text nodes (and not bother with any HTML elements).  This will allow us to insert the unicode hyphen between the characters of text nodes, while leaving in tact all other HTML inside the bound element.</p>
	<p>The code would look something like this:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="kw2">var</span> walker = document.<span class="me1">createTreeWalker</span><span class="br0">&#40;</span>_elem, NodeFilter.<span class="me1">SHOW_TEXT</span>, <span class="kw2">null</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;</p>
	<p><span class="kw1">while</span> <span class="br0">&#40;</span>walker.<span class="me1">nextNode</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> node = walker.<span class="me1">currentNode</span>;<br />
&nbsp; &nbsp;node.<span class="me1">nodeValue</span> = node.<span class="me1">nodeValue</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">''</span><span class="br0">&#41;</span>.<span class="me1">join</span><span class="br0">&#40;</span>String.<span class="me1">fromCharCode</span><span class="br0">&#40;</span><span class="st0">'8203'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
	<p>The above code is really a tremendous simplification from what I had originally written (thanks Rich!).  This technique allows us to walk only the text nodes of the bound element (skipping over any HTML tags).  That way, we can insert the unicode symbol only amongst the characters of raw text and not have to worry about mangling (and subsequently, unmangling) any HTML tags.</p>
	<h3>The "Gotcha:"</h3>
	<p>While the TreeWalker technique greatly simplifies the word-wrap binding code, there is still a caveat that you should be aware of if you plan to use this binding -- or a similar one you've written yourself -- in one of your projects (and this goes for the original version too).</p>
	<p>Inserting the unicode symbol between <em>every</em> character in a string is not necessarily ideal.  Take a perfectly normal string like "How are you today?"  This string already has spaces, and so it will naturally wrap where the browser sees those "soft" spaces.  Inserting the unicode hyphen into that aforementioned string doesn't do anything particularly useful, and in fact, it might even be considered harmful.</p>
	<p>It's quite possible that you would end up breaking the word "today" onto two pieces: "tod" and "ay" -- clearly not the desired effect.  What can be done about this?  Well... one option is careful and thoughtful use of the word-wrap binding.  Use it only for long <em>unbroken</em> strings of text (like a long URL for instance).  Another option might be to modify the code to abort the word wrap if a space is found within the string (far from a perfect approach though).</p>
	<p>Another idea I experimented with (but decided against blogging about because of its complexity) was measuring each "word" in the bound element.  If any given word were greater in width than the bound element's container, then <em>that</em> word would get unicode hyphens inserted into it.  All "short" words were left alone.</p>
	<p>This technique did actually work, but it involved recursively adding invisible, cloned elements wrapped in &lt;span&gt; tags to the DOM on the fly in order to properly measure the text.  Also, it did not account for a scenario where text should wrap because of a floated element, and this (IMO) is one of the more desirable way to utilize word-wrap.  Still, I think the concept has potential, and I may decide to revisit it at some point in the future.</p>
	<p>For now though, we have something that gets us close, is relatively simple to implement, and brain-dead easy to use.</p>
	<p>If you'd like, you can see a working demo of the <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take2/">updated word-wrap code</a>.</p>
	<p>If you're feeling extra adventurous, you can take a look at my <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take3/">word-wrap experiment (take 3)</a> where I try to measure text elements and only insert unicode hyphens where necessary (use this version at your own risk!)</p>
	<p>That'll do it for this entry.  Special thanks to Rich Birkby for enlightening me about the TreeWalker.  Be sure to check our Rich's ASPAdvice blog: <a href = "http://aspadvice.com/blogs/rbirkby/">http://aspadvice.com/blogs/rbirkby</a> and his <a href = "http://www.thundermain.com/rss">Microsoft Downloads RSS Feed</a>.</p>
	<p>Comments welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Emulating CSS word-wrap for Mozilla/Firefox</title>
		<link>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/</link>
		<comments>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 07:46:40 +0000</pubDate>
		<dc:creator>sstchur</dc:creator>
				<category><![CDATA[CSS Related]]></category>
		<category><![CDATA[Cross-Browser]]></category>
		<category><![CDATA[Mozilla-specific]]></category>

		<guid isPermaLink="false">http://stchur.com/blog2/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/</guid>
		<description><![CDATA[	
	Be sure to check out the follow-up to this post:  Word-wrap for Mozilla (take 2).  It features a much simplified way of accomplishing the same thing, based on the comments from RichB.
	
	IE has one nice CSS feature that a lot of other browsers lack, which is the ability to use CSS to wrap [...]]]></description>
			<content:encoded><![CDATA[	<div class = "note">
	<p>Be sure to check out the follow-up to this post:  <a href = "http://ecmascript.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Word-wrap for Mozilla (take 2)">Word-wrap for Mozilla (take 2)</a>.  It features a much simplified way of accomplishing the same thing, based on the comments from RichB.</p>
	</div>
	<p>IE has one nice CSS feature that a lot of other browsers lack, which is the ability to use CSS to wrap long words.  It's easy to use.  Something like this will do the trick:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="re1">.wrapme</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;word-wrap: break-word;<br />
<span class="br0">&#125;</span></div>
	<p>Firefox lacks this feature, but it does offer some snazzy features of its own.  One in particular is <a href = "http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference"><abbr title = "Extensible Binding Language">XBL</abbr></a>.</p>
	<p>In this blog entry, I'm going to demonstrate how to use Mozilla Bindings to (sort of) emulate CSS word-wrap.  Since the ability to wrap a long series of unbroken characters is part of the CSS3 specification, I do expect to see this in future versions of Firefox.  Until then, this is the best I've got.</p>
	<h3>An outside-the-box solution</h3>
	<p>For a long time, I didn't think there was really anything you could do about Firefox's lack of support for <code>word-wrap</code>.  I figured the best you could do was set your containing element to hide overflowing data (which might be okay, but most likely not).</p>
	<p>Just recently though, a co-worker of mine found a web page that explained how you could insert an invisible unicode character (&amp;#8203;) at various points in a string to solve the Firefox word-wrap problem.  Since Firefox views this unicode symbol as a valid character upon which to "break" a string (if necessary) it servers as a convenient to way get Firefox to wrap long strings of characters (the symbol remains completely invisible to the end user).</p>
	<p>My co-worker first showed me a function he wrote which took a string parameter, inserted this unicode symbol every 5 characters, and then returned the modified string.</p>
	<p>This is a good first start, but I wanted something more.  I wanted a solution that didn't require me to execute a Javascript function, and I wanted a solution that could handle HTML intersperced throughout the string.</p>
	<p>It turns out, that creating a solution that <em>doesn't</em> require executing a Javascript function isn't the hard part at all!  In Firefox, this can be accomplished quite easily with <a href = "http://developer.mozilla.org/en/docs/XBL:XBL_1.0_Reference"><abbr title = "Extensible Binding Language">XBL</abbr></a>.</p>
	<p>How does one utilize <abbr title = "Extensible Binding Language">XBL</abbr>? Glad you asked!</p>
	<p>From the Mozilla Developer page:</p>
	<blockquote><p>
Extensible Binding Language is a XML-based markup language to implement reusable components (bindings) that can be bound to elements in other documents. The element with a binding specified, called the bound element, acquires the new behavior specified by the binding. Bindings can be bound to elements using Cascading Style Sheets (CSS) or DOM. One element can be be bound to several bindings at once.<br />
</blockquote></p>
	<p>Setting up the binding is pretty easy, so let's tackle that part first:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="re1">.wordwrap</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;-moz-binding: <span class="kw2">url</span><span class="br0">&#40;</span><span class="st0">'./wordwrap.xml#wordwrap'</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
	<p>With the CSS in place, "binding" to the DOM element is trivial:  simply set the element's class property to "wordwrap".</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="sc3"><span class="re1">&lt;p</span> id = <span class="st0">&quot;myParagraph&quot;</span> class = <span class="st0">&quot;wordwrap&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp;SomeParagraphWithAVeryLongStringOfUnbrokenTextThatWillEventuallyWrap.<br />
<span class="sc3"><span class="re1">&lt;/p<span class="re2">&gt;</span></span></span></div>
	<p>With the CSS and HTML taken care of, all that's left to do is write the XBL file.  An XBL file is really nothing more than an XML with a specific structure so that Mozilla knows how to process it as a binding.  In fact, if you prefer, you can name the file with an <code>.xml</code> extension (like I did), instead of an <code>.xbl</code> extension.</p>
	<p>At its most basic, an XBL file takes the following form:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="sc3"><span class="re1">&lt;?xml</span> version = <span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;bindings</span> xmlns = <span class="st0">&quot;http://www.mozilla.org/xbl&quot;</span> xmlns:html = <span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="re2">&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;binding</span> id = <span class="st0">&quot;wordwrap&quot;</span> applyauthorstyles = <span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span></p>
	<p>&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;implementation<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;/* ECMAScript code here */<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;/constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;/implementation<span class="re2">&gt;</span></span></span></p>
	<p><span class="sc3"><span class="re1">&lt;/binding<span class="re2">&gt;</span></span></span></p>
	<p><span class="sc3"><span class="re1">&lt;/bindings<span class="re2">&gt;</span></span></span></div>
	<h3>The binding id attribute:</h3>
	<p>The root element of the file is &lt;bindings&gt;.  Within the root element, you'll have one or more &lt;binding&gt; elements, each with its own unique id.  Since an XBL file can have more than one binding definition, the id instructs the browser as to which binding we're interested in.  Remember, back when we specified the url for the -moz-binding property, we specified the binding id by appending to it, a "#" symbol followed by the binding id (in this case "wordwrap").  So the full url ended up being: <code>"./wordwrap.xml#wordwrap"</code>.</p>
	<h3>The applyauthorstyles attribute:</h3>
	<p>The "applyauthorstyles" attribute determines whether or not to allow styles from the document on the bound element (other than the -moz-binding).  The default value is false, but you're free to change this if you want (or need) to.</p>
	<h3>The &lt;implementation&gt; and &lt;constructor&gt;</h3>
	<p>Every binding has an &lt;implementation&gt; element and, within it, a &lt;constructor&gt; element.  This is where most of your ECMAScript code will go (in our case, this is where <em>all</em> of the ECMAScript code will go).</p>
	<p>With a <em>very</em> basic explanation of an XBL file's structure out of the way, we can now go ahead and write the implementation of our binding.</p>
	<p>It's important to note that all of the ECMAScript you write needs to go inside a CDATA block (this an XML file after all).  Other than that though, you don't have too many restrictions.  In fact, one nice thing about writing a binding, is that you have a great deal of flexibility.  Pretty much all of the ECMAScript you're used to writing is going to work inside the XBL file.  And to sweeten the deal even more, you've got some nice extras that aren't available in your normal, day-to-day ECMAScript (we'll look at one of them shortly).</p>
	<h3>Referencing the bound element:</h3>
	<p>Perhaps the most important thing you need to know (before you can do anything productive in your binding) is how access the bound element.  In other words, how do you access the element to which the class (in our case "wordwrap") was applied?  Fortunately, it turns out to be brain-dead easy.  You simply using the <code>this</code> keyword; that's it!</p>
	<p>Once you have a reference to the bound element, you can do most (if not all) of the things you'd normally do with a DOM element.  You could, for instance, wire up logic such that a particular function execute whenever the bound element is moused over, as in:</p>
	<div class="dean_ch" style="white-space: nowrap;"><span class="kw2">var</span> elem = <span class="kw1">this</span>;<br />
elem.<span class="me1">addEventListener</span><span class="br0">&#40;</span><span class="st0">'mouseover'</span>, <span class="kw2">function</span><span class="br0">&#40;</span>e<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">'The text of this element will eventually be wrapped!'</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span>, <span class="kw2">false</span><span class="br0">&#41;</span>;</div>
	<p>If you put the preceding code inside the &lt;constructor&gt; element of the binding definition, then any time a user moused over the &lt;p&gt; (#myParagraph), he would see an alert saying "The text of this element will eventually be wrapped!"</p>
	<h3>Making the text wrap:</h3>
	<p>At this point, it should be fairly clear what the plan of action is:</p>
	<ol>
	<li>Access the bound element's text.</li>
	<li>Insert the special unicode symbol between the characters of the string.</li>
	<li>Update the bound element's text with the newly modified text.</li>
	</ol>
	<p>From the instructions above, I've made it sounds pretty simple.  Unfortunately, it's a bit more complicated than I let on.  I (conveniently) failed to mention that if the bound element's text contains HTML, we need to take extra care not to insert the special unicode symbol into any of the HTML tags (or else we'll end up disrupting the author's markup).</p>
	<div class = "note">
Actually, the final solution I came up with <em>doesn't</em> take care not to insert the special unicode symbol into HTML tags.  Instead, I willingly make a mess out of the markup and then write a bit of logic to clean it up later on, but I'll explain all of that as we get further into the binding's ECMAScript code.</div>
	<h3>The word wrap code</h3>
	<p>The code to make this happen isn't long, so rather than try to explain it up front, I'll first show the full code, and then provide an explanation afterwards:</p>
	<div class="dean_ch" style="white-space: nowrap;">
<span class="sc3"><span class="re1">&lt;?xml</span> version = <span class="st0">&quot;1.0&quot;</span><span class="re2">?&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;bindings</span> xmlns = <span class="st0">&quot;http://www.mozilla.org/xbl&quot;</span> xmlns:html = <span class="st0">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="re2">&gt;</span></span></p>
	<p><span class="sc3"><span class="re1">&lt;binding</span> id = <span class="st0">&quot;wordwrap&quot;</span> applyauthorstyles = <span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span></p>
	<p>&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;implementation<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;constructor<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var elem = this;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// maintain a reference to the bound element</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;elem.addEventListener('overflow',<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;function()<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;// matches any &quot;mangled&quot; HTML tag<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var exp = /<span class="sc3"><span class="re1">&lt;</span>&amp;#<span class="nu0">8203</span>;\/*<span class="br0">&#91;</span>&amp;#<span class="nu0">8203</span>;_\<span class="re0">s</span>=<span class="st0">&quot;'\w]+&gt;</span>/g;</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var txt = elem.innerHTML;&nbsp; &nbsp; &nbsp;// the bound element's innerHTML<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var chars = txt.split('');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;var newTxt = chars.join('<span class="sc1">&amp;#8203;</span>');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;newTxt = newTxt.replace(exp, reconstructTag);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;elem.innerHTML = newTxt;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;},false);</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;function reconstructTag(_tag)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return _tag.replace(/<span class="sc1">&amp;#8203;</span>/g, '');<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}</p>
	<p>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//<br />
&nbsp; &nbsp;&nbsp; &nbsp;<span class="sc3">&lt;/constructor&gt;</span><br />
&nbsp; &nbsp;<span class="sc3">&lt;/implementation&gt;</span></p>
	<p><span class="sc3">&lt;/binding&gt;</span></p>
	<p><span class="sc3">&lt;/bindings&gt;</span></span></div>
	<h3>Explanation:</h3>
	<p>The first thing we do is stuff the bound element (<code>this</code>) in a variable, <code>elem</code>.  This is of course, totally optional, but it helps me (my brain is small and remembering what <code>this</code> represents eludes me quickly and frequently).</p>
	<p>Next, we add an event listener to the bound element that "listens" for the 'overflow' event (whenever text overflows its containing element).  You're probably aware the in typical Javascript, there is no such 'overflow' event.  This, along with its counterpart, 'underflow' are just two the many "extras" that you get when writing Javascript in XBL.</p>
	<p>The remainder of the code will all take place within the context of the anonymous function that executes on 'overflow'.</p>
	<p>Next, we create a regular expression that matches any "mangled" HTML tag (more on this in a bit).</p>
	<p>The next three steps are all quite straight-forward. We store the bound element's innerHTML in a variable called, <code>txt</code>.  We then call <code>.split('')</code> on that text and store it in the variable, <code>chars</code>.  Passing an empty string into the <code>.split(..)</code> function will yield an array of characters representing the string that was split.  In other words, each character in the string is now an element in the array <code>chars</code>.  Finally, we put all of those characters back together by calling <code>chars.join('&amp;#8203');</code> and stuffing the result in <code>newTxt</code>.  This inserts that special unicode symbol between each character in the array as it joins them back together.</p>
	<h3>The tricky part:</h3>
	<p>If you were paying attention, then at this point, you'd realize that any HTML that existed inside of the bound element, just got totally mangled with that last <code>.join(..)</code>. statement.  Think about it: if the bound element's innerHTML were something like this:</p>
	<div class="dean_ch" style="white-space: nowrap;">This &lt;span&gt;is a&lt;/span&gt; paragraph.</div>
	<p>Then after executing the <code>.join(..)</code> statement, the variable, <code>newTxt</code> would now be equal to:</p>
	<div class="dean_ch" style="white-space: nowrap;">&amp;amp;#8203;T&amp;amp;#8203;h&amp;amp;#8203;i&amp;amp;#8203;s&amp;amp;#8203; &amp;amp;#8203;&lt;&amp;amp;#8203;s&amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;n&amp;amp;#8203;&gt;&amp;amp;#8203;i&amp;amp;#8203;s&amp;amp;#8203; &amp;amp;#8203;a&amp;amp;#8203;&lt;&amp;amp;#8203;/&amp;amp;#8203;s&amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;n&amp;amp;#8203;&gt;&amp;amp;#8203; &amp;amp;#8203;p&amp;amp;#8203;a&amp;amp;#8203;r&amp;amp;#8203;a&amp;amp;#8203;g&amp;amp;#8203;r&amp;amp;#8203;a&amp;amp;#8203;p&amp;amp;#8203;h&amp;amp;#8203;.&amp;amp;#8203;</div>
	<p>Besides perhaps giving you a head-ache, the above HTML snippet should make you realize that the insertion of that special unicode symbol between <em>every</em> character in the string has a really detrimental effect on the &lt;span&gt; tag.</p>
	<h3>The solution:</h3>
	<div class = "note">
The <a href = "http://ecmascript.stchur.com/2007/03/01/word-wrap-for-mozilla-take-2/" title = "Word-wrap for Mozilla (take 2)">follow-up</a> to this post explains a much easier method that doesn't involve mangling the HTML.  It is highly recommended that you check out that approach as well.
</div>
	<p>It turns out, that "unmangling" the HTML tags isn't too too hard (just takes some fancy regular expression work).  The regular expression, <code>exp</code> will match any HTML tag that has had the special unicode symbol inserted into it.  We can utilize this regular expression to match all occurrences of "mangled" HTML tags and (with some help from the <code>.replace(..)</code> function) replace them with "unmangled" versions of the tag.</p>
	<p>In order to do this though, we need to make of use a callback function when we invoke the <code>.replace(..)</code> function.  When you pass a function reference as the second parameter into a <code>.replace(..)</code> call (as in: <code>myString.replace(regex, myFn)</code>) Javascript will automatically pass the matched string into the callback function for you!</p>
	<p>This is an extremely powerful concept.  We can now take all "mangled" HTML tag matches and send them through the <code>reconstructTag(..)</code> function.  The <code>reconstructTag(..)</code> function simply returns a copy of the string sent into it, but with all occurrences of that special unicode symbol stripped out (thus returning our "mangled" HTML tags to proper form).</p>
	<p>With all of these concepts working together, we end up with a string that looks perfectly unaltered to the end user, but which wraps nicely when it would otherwise overflow its container.</p>
	<p>See for yourself on my demo page: <a href = "http://ecmascript.stchur.com/blogcode/emulating_word_wrap/">Word Wrap Binding Demo</a>.</p>
	<p>And, to see a slightly more complex example, take a look at my implementation of an ellipsis for Mozilla using XBL: <a href = "http://ecmascript.stchur.com/blogcode/mozilla_ellipsis/">Mozilla Ellipsis</a>.</p>
	<h3>Final thoughts:</h3>
	<p>Mozilla Bindings offer tremendous power to the developer.  You can do virtually <em>anything</em> with them; the sky is the limit really.  In this blog post, we just looked at one example: how to make long, unbroken strings wrap when they would otherwise overflow their container.  But we also saw how you can take this further (see the ellipsis demo link above).</p>
	<h3>Important Warning / Disclaimer!</h3>
	<p>It should be noted that I have absolutely <em>no idea</em> what kind of effect inserting the special unicode symbol (needed to make this technique work) might have on accessibility.  It's an important question.  Is that character going to be read aloud by screen readers (what in the world would it say)?  Will search engines see it and have no idea what your text represents, thereby hurting your search engine ranking?  My fear is that the effect of inserting this character into your string might not be good.  But of course, without any real testing, I can't say for sure.</p>
	<p>My recommendation would be to use this concept with caution and only when absolutely necessary.  A little common sense will go along way towards ensuring you're not bloating your page will a lot of "fancy-just-for-the-heck-of-it" code.</p>
	<p>So there ya go!  Word wrap in Mozilla.  Happy Binding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.stchur.com/2007/02/22/emulating-css-word-wrap-for-mozillafirefox/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
	</channel>
</rss>
