<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Tales from the Evil Empire : Firefox</title><link>http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx</link><description>Tags: Firefox</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>JavaScript Behavior Sheets: an experiment</title><link>http://weblogs.asp.net/bleroy/archive/2009/01/18/javascript-behavior-sheets-an-experiment.aspx</link><pubDate>Sun, 18 Jan 2009 08:53:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6843536</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6843536</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2009/01/18/javascript-behavior-sheets-an-experiment.aspx#comments</comments><description>&lt;P&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 7px 0px 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="(c) Bertrand Le Roy 2004" border=0 alt="(c) Bertrand Le Roy 2004" align=left src="http://weblogs.asp.net/blogs/bleroy/ZenShadows_7A57622D.jpg" width=164 height=244 mce_src="http://weblogs.asp.net/blogs/bleroy/ZenShadows_7A57622D.jpg"&gt; Here’s a little experiment. I’m really after feedback on this one as I’m trying to decide whether this is a good idea. It’s also entirely possible somebody else did this before. That would be good feedback too. Anyway, here it is.&lt;/P&gt;
&lt;P&gt;Despite its shortcomings, CSS has a number of features that make it very compelling. First, it decouples styling from markup. Second, its selector syntax is simple, yet reasonably powerful.&lt;/P&gt;
&lt;P&gt;So we have semantic markup on the one hand, and styles on the other hand, and the only coupling between the two is the selectors in the stylesheet.&lt;/P&gt;
&lt;P&gt;In Ajax applications, there is a third kind of entity in the mix, JavaScript behavior. There are of course ways to decouple the script behavior from the markup, which are usually referred to as &lt;A href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript" mce_href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;unobtrusive JavaScript&lt;/A&gt;. &lt;A href="http://www.jquery.com/" mce_href="http://www.jquery.com"&gt;jQuery&lt;/A&gt; &lt;FONT face="Courier New"&gt;also &lt;/FONT&gt;introduced back in 2005 a way to associate script behavior with the DOM using the same selector syntax that CSS uses.&lt;/P&gt;
&lt;P&gt;But way before &lt;A href="http://jquery.com/" mce_href="http://jquery.com/"&gt;jQuery&lt;/A&gt;, &lt;A href="http://msdn.microsoft.com/en-us/library/ms532147.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms532147.aspx"&gt;Internet Explorer 5 enabled developers to specify behavior in stylesheets&lt;/A&gt;. You could do this for example:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #a31515"&gt;.hilite &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: red"&gt;behavior&lt;/SPAN&gt;:&lt;SPAN style="COLOR: blue"&gt;url(hilite.htc) &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This was a pretty neat idea at the time despite the challenges that came with it (in terms of performance for example), but it was never adopted by the other browsers despite having been &lt;A href="http://www.w3.org/TR/1999/WD-becss-19990804.html" mce_href="http://www.w3.org/TR/1999/WD-becss-19990804.html"&gt;submitted to W3C&lt;/A&gt;. The feature was never very widely used. There *is* &lt;A href="http://dean.edwards.name/moz-behaviors/overview/" mce_href="http://dean.edwards.name/moz-behaviors/overview/"&gt;a Firefox implementation of HTC behaviors&lt;/A&gt; but it doesn’t seem to have helped much in terms of adoption of this feature.&lt;/P&gt;
&lt;P&gt;And one thing that bothers me with that idea is that while it does decouple behavior from markup, it also &lt;EM&gt;couples&lt;/EM&gt; behavior to styling at least in location. Putting styles and behavior in the same file, in retrospect, looks like one step forward, and one step backwards. Sure, you could always use two separate files but the system did nothing to encourage you to do that.&lt;/P&gt;
&lt;P&gt;What I’m trying to do here is separate styling, markup *and* behavior, leverage selectors in a nice, declarative way &lt;EM&gt;à la&lt;/EM&gt; CSS and still work on all modern browsers. The coupling mechanism between style and markup (CSS selectors), is reasonably good and is already known by all Web developers so it remains a natural choice as jQuery showed clearly. Let’s see if one can express behavior in a way that is close to the already well-known CSS pattern.&lt;/P&gt;
&lt;P&gt;In this implementation, it is possible to add event handlers and Microsoft Ajax behaviors from a “JavaScript Behavior Sheet” which can be embedded in the page or be loaded from a separate file using a modified script tag:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="text/behavior" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;src&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="BehaviorSheet.jss"&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The contents of the tag or file is in the simple JSON notation for an object, omitting the curly braces:&lt;/P&gt;&lt;PRE class=code&gt;"input[type=text].nomorethanfive": {
    click: function(e) {
        alert("You clicked input #" + e.target.id);
    },
    "Bleroy.Sample.CharCount": {
        maxLength: 5,
        overflow: function(source, args) {
            $(source.get_element()).jFade({
                 property: 'background',
                 start: 'FFFF00',
                 end: 'FFFFFF',
                 steps: 25,
                 duration: 30
            });
        }
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The top-level entities that can be found in there are the CSS selectors (note the quotes that &lt;EM&gt;are&lt;/EM&gt; a departure from CSS notation but made the prototyping so much simpler). Each selector is associated with an object that contains event and object definitions.&lt;/P&gt;
&lt;P&gt;The event definitions consist in the event name and the handler to associate with it:&lt;/P&gt;&lt;PRE class=code&gt;click: function(e) {
    alert("You clicked input #" + e.target.id);
},&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The implementation of this feature uses the new &lt;A href="http://docs.jquery.com/Events/live#typefn" mce_href="http://docs.jquery.com/Events/live#typefn"&gt;live events from jQuery&lt;/A&gt;. The result of that definition is that clicking on any input of type text with the class “nomorethanfive” will display an alert giving the id of the input that was clicked. That is a pretty efficient way to hook up events to multiple elements…&lt;/P&gt;
&lt;P&gt;The behavior instantiation specifies the class to instantiate, “Bleroy.Sample.CharCount” and lists the properties, fields and events to set (here, the maxLength property is set to 5 and the overflow event is hooked to a function that flashes the element’s background yellow):&lt;/P&gt;&lt;PRE class=code&gt;"Bleroy.Sample.CharCount": {
    maxLength: 5,
    overflow: function(source, args) {
        $(source.get_element()).jFade({
             property: 'background',
             start: 'FFFF00',
             end: 'FFFFFF',
             steps: 25,
             duration: 30
        });
    }
}&lt;/PRE&gt;
&lt;P&gt;Here’s what the page looks like: &lt;BR&gt;&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:beb84b52-ccf2-4861-9ec4-3bb1f8e468bc class=wlWriterEditableSmartContent&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-TOP: 0px" id=4314ce20-b9b6-441e-9466-068510fa6144&gt;
&lt;DIV&gt;&lt;A href="http://video.msn.com/video.aspx?vid=bd271e94-33e0-46fd-a09f-17c5ebe09f11" target=_new&gt;&lt;IMG style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-TOP-STYLE: none; BORDER-LEFT-STYLE: none" alt="" src="http://weblogs.asp.net/blogs/bleroy/videofbd13523437b_5803F39D.jpg" onload="var downlevelDiv = document.getElementById('4314ce20-b9b6-441e-9466-068510fa6144'); downlevelDiv.innerHTML = &amp;quot;&lt;div&gt;&lt;embed src=\&amp;quot;http://images.video.msn.com/flash/soapbox1_1.swf\&amp;quot; quality=\&amp;quot;high\&amp;quot; width=\&amp;quot;432\&amp;quot; height=\&amp;quot;364\&amp;quot; wmode=\&amp;quot;transparent\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; pluginspage=\&amp;quot;http://macromedia.com/go/getflashplayer\&amp;quot; flashvars=\&amp;quot;c=v&amp;amp;v=bd271e94-33e0-46fd-a09f-17c5ebe09f11&amp;amp;from=writer&amp;amp;mkt=en-US\&amp;quot; &gt;&lt;\/embed&gt;&lt;\/div&gt;&amp;quot;;" galleryimg="no"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;I should point out that while the events will handle DOM mutations (such as adding new elements that match the selector) just fine, component instantiation won’t in this implementation, which is a limitation that is quite hard to work around in current browsers.&lt;/P&gt;
&lt;P&gt;So here it is. All the code for this is &lt;A href="http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip" mce_href="http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip"&gt;available from the link below&lt;/A&gt; (contains &lt;A href="http://www.gimiti.com/kltan/wordpress/?p=43" mce_href="http://www.gimiti.com/kltan/wordpress/?p=43"&gt;jFade&lt;/A&gt;, code licensed under &lt;A href="http://opensource.org/licenses/mit-license.php" mce_href="http://opensource.org/licenses/mit-license.php"&gt;MIT&lt;/A&gt;: &lt;A href="http://jquery.com/" mce_href="http://jquery.com/"&gt;jQuery&lt;/A&gt;, and code under &lt;A href="http://opensource.org/licenses/ms-pl.html" mce_href="http://opensource.org/licenses/ms-pl.html"&gt;MS-PL&lt;/A&gt;: &lt;A href="http://www.asp.net/ajax/" mce_href="http://www.asp.net/ajax/"&gt;Microsoft Ajax&lt;/A&gt; and my own code), with some tests written with &lt;A href="http://weblogs.asp.net/bleroy/archive/2008/12/09/really-simple-testing-for-javascript.aspx" mce_href="http://weblogs.asp.net/bleroy/archive/2008/12/09/really-simple-testing-for-javascript.aspx"&gt;RST.js&lt;/A&gt;. So what do you think?&lt;/P&gt;
&lt;P&gt;&lt;A title=http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip href="http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip" mce_href="http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip"&gt;http://weblogs.asp.net/blogs/bleroy/Samples/BehaviorSheet.zip&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; interestingly, the intent behind &lt;A href="http://code.google.com/p/reglib/"&gt;Reglib&lt;/A&gt; by &lt;A href="http://blogs.sun.com/greimer/"&gt;Greg Reimer&lt;/A&gt; is pretty close to this and he even uses the words “Behavior Sheets”.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; Stuart Langridge did &lt;A href="http://www.kryogenix.org/code/browser/jses/" mce_href="http://www.kryogenix.org/code/browser/jses/"&gt;something very close to declarative events as they are done here&lt;/A&gt; &lt;EM&gt;back in November 2003&lt;/EM&gt;. Thanks to Clayton for pointing that out. One should note that the limitations of the time are no longer preventing the technique from reaching its full potential.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6843536" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JSON/default.aspx">JSON</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx">Firefox</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/jQuery/default.aspx">jQuery</category></item><item><title>Why are scripts slow to load in Firefox when using Visual Studio’s built-in development Web server (a.k.a. Cassini)?</title><link>http://weblogs.asp.net/bleroy/archive/2008/12/29/why-are-scripts-slow-to-load-in-firefox-when-using-visual-studio-s-built-in-development-web-server-a-k-a-cassini.aspx</link><pubDate>Mon, 29 Dec 2008 20:41:30 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6808763</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6808763</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2008/12/29/why-are-scripts-slow-to-load-in-firefox-when-using-visual-studio-s-built-in-development-web-server-a-k-a-cassini.aspx#comments</comments><description>&lt;p&gt;If you’ve been doing some script development in Visual Studio and Firebug, you may have experienced something like this:    &lt;br /&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Slow script loading with Firefox and Cassini" border="0" alt="Slow script loading with Firefox and Cassini" src="http://weblogs.asp.net/blogs/bleroy/SlowFFCassini_57BA2A66.png" width="504" height="181" /&gt; &lt;/p&gt;  &lt;p&gt;Notice how all resources take more than a second to load? Loading of scripts being sequential doesn’t help either.&lt;/p&gt;  &lt;p&gt;And of course, the more scripts you have on the page, the worse it gets. I’ve seen fairly simple pages take around 15 seconds to load because of this bug.&lt;/p&gt;  &lt;p&gt;I’m not quite sure where that bug comes from, but the good news is I have two solutions for you. First, you can configure Visual Studio to use IIS (when you do “new web site”, choose HTTP as the location, then “local IIS”). But the easiest is just to replace “localhost” in the browser address bar with “127.0.0.1”. Here’s the performance of the same page as above, using that address:    &lt;br /&gt;&lt;a href="http://weblogs.asp.net/blogs/bleroy/FastFFCassini_2B30FA80.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="FastFFCassini" border="0" alt="FastFFCassini" src="http://weblogs.asp.net/blogs/bleroy/FastFFCassini_thumb_115CC451.png" width="504" height="179" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;From 6 seconds down to 215 milliseconds. Not bad, eh? Multiply this by the number of times you load pages in this configuration during a typical work day and you’ve got what I think is a pretty useful trick ;) Of course, not having this bug in the first place would be ideal…&lt;/p&gt;  &lt;p&gt;I hope this helps.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;&lt;a href="http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx"&gt;Dan Wahlin has an explanation for this&lt;/a&gt;, which is an issue with DNS and IPv6 support in Firefox. An alternate workaround is to disable IPv6 in Firefox. Thanks to Marc for pointing me to this post.    &lt;br /&gt;&lt;a title="http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx" href="http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx"&gt;http://weblogs.asp.net/dwahlin/archive/2007/06/17/fixing-firefox-slowness-with-localhost-on-vista.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6808763" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx">Firefox</category></item><item><title>Web development best practices finally made fun</title><link>http://weblogs.asp.net/bleroy/archive/2008/04/02/web-development-best-practices-finally-made-fun.aspx</link><pubDate>Wed, 02 Apr 2008 23:23:18 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6062044</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6062044</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2008/04/02/web-development-best-practices-finally-made-fun.aspx#comments</comments><description>&lt;div style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px; display: inline" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:4a6f3336-310a-4593-ad21-d643da0091f6" class="wlWriterSmartContent"&gt;&lt;div id="1fc433ba-3388-459d-80da-ea7325f3f7b9" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=a0qMe7Z3EYg&amp;amp;hl=en" target="_new"&gt;&lt;img src="http://weblogs.asp.net/blogs/bleroy/WindowsLiveWriter/Webdevelopmentbestpracticesfinallymadefu_E672/videob0b9f54899c6.jpg" galleryimg="no" onload="var downlevelDiv = document.getElementById('1fc433ba-3388-459d-80da-ea7325f3f7b9'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;350\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/a0qMe7Z3EYg&amp;amp;hl=en\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;param name=\&amp;quot;wmode\&amp;quot; value=\&amp;quot;transparent\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/a0qMe7Z3EYg&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; wmode=\&amp;quot;transparent\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;350\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6062044" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Safari/default.aspx">Safari</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Opera/default.aspx">Opera</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx">Firefox</category></item><item><title>OpenAjax requests comments on browser wishlist</title><link>http://weblogs.asp.net/bleroy/archive/2008/04/01/openajax-requests-comments-on-browser-wishlist.aspx</link><pubDate>Tue, 01 Apr 2008 17:13:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6057153</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=6057153</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2008/04/01/openajax-requests-comments-on-browser-wishlist.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;The OpenAjax Alliance has been working with&amp;nbsp;some of the top Ajax developers&amp;nbsp;on a wishlist that aims at gathering and prioritizing the development features that we need the most from next generation browsers. The process is completely open and Wiki-based, so feel free to contribute.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;U&gt;&lt;FONT color=#800080&gt;&lt;A href="http://www.openajax.org/blogs/wp-trackback.php?p=53"&gt;http://www.openajax.org/blogs/wp-trackback.php?p=53&lt;/A&gt;&lt;/FONT&gt;&lt;/U&gt;&lt;A href="http://www.openajax.org/blogs/?p=53" mce_href="http://www.openajax.org/blogs/?p=53"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6057153" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/OpenAjax/default.aspx">OpenAjax</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Safari/default.aspx">Safari</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Opera/default.aspx">Opera</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx">Firefox</category></item><item><title>Getting absolute coordinates from a DOM element</title><link>http://weblogs.asp.net/bleroy/archive/2008/01/29/getting-absolute-coordinates-from-a-dom-element.aspx</link><pubDate>Wed, 30 Jan 2008 01:51:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5673801</guid><dc:creator>Bertrand Le Roy</dc:creator><slash:comments>20</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/bleroy/rsscomments.aspx?PostID=5673801</wfw:commentRss><comments>http://weblogs.asp.net/bleroy/archive/2008/01/29/getting-absolute-coordinates-from-a-dom-element.aspx#comments</comments><description>&lt;P&gt;For some reason, there is no standard API to get the pixel coordinates of a DOM element relative to the upper-left corner of the document. APIs only exist to get coordinates relative to the offset parent. Problem is, it's very important to get those coordinates for applications such as drag and drop, or whenever you need to compare coordinates of elements that may be in completely different parts of the document.&lt;/P&gt;
&lt;P&gt;In Microsoft Ajax, &lt;A class="" href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetLocationMethod.aspx" mce_href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetLocationMethod.aspx"&gt;we implemented such a function&lt;/A&gt;&amp;nbsp;(&lt;A class="" href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetLocationMethod.aspx" mce_href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/DomElementClass/SysUIDomElementGetLocationMethod.aspx"&gt;Sys.UI.DomElement.getLocation&lt;/A&gt;) but it proved to be one of the most difficult problems we had to solve. Not so surprisingly, every single browser has its own coordinate quirks that make it almost impossible to get the right results with just capability detection. This is one of the very rare cases where we reluctantly had to use browser sniffing and implement a completely different version of the function for each browser.&lt;/P&gt;
&lt;P&gt;We also had to implement a pretty complex test suite to verify our algorithms for thousands of combinations of block or inline elements, offsets, scroll positions, frame containment, borders, etc., and run those on each browser that we support. The test suite in itself is quite interesting: it renders an element with the constraints to test, gets its coordinates from the API, creates a top-level semi-transparent element that is absolutely positioned and check that both overlap exactly to pixel precision. To do so, it takes a screen shot and analyses the image to find the rectangles and check their color.&lt;/P&gt;
&lt;P&gt;The simplest runtime implementation is the IE one, thanks to a little-known API that does almost exactly what we want: &lt;A href="http://msdn2.microsoft.com/en-us/library/ms536433.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms536433.aspx"&gt;getBoundingClientRect&lt;/A&gt;. &lt;EM&gt;Almost&lt;/EM&gt; exactly as we quickly discovered it has a weird 2-pixel offset except on IE6 if the HTML element has a border (which is a "feature" that was removed in IE7 and which we chose not to support). It also doesn't include the document's scroll position. Finally, if the element is in a frame, the frame border should be subtracted. This actually was the cause for &lt;A href="http://weblogs.asp.net/bleroy/archive/2007/01/31/how-to-work-around-the-quot-access-denied-quot-cross-domain-frame-issue-in-asp-net-ajax-1-0.aspx" mce_href="http://weblogs.asp.net/bleroy/archive/2007/01/31/how-to-work-around-the-quot-access-denied-quot-cross-domain-frame-issue-in-asp-net-ajax-1-0.aspx"&gt;a bug&lt;/A&gt; that we unfortunately discovered after we shipped 1.0 but which is now fixed in ASP.NET 3.5 as the parent frame may not be in the same domain, in which case attempting to get its frame border will result in an access denied error. So you need to do this in a try-catch and just accept the bad offset in that fringe scenario.&lt;/P&gt;
&lt;P&gt;In all other browsers, you currently need to recurse through the offset parents of the element and sum the offset coordinates.&lt;/P&gt;
&lt;P&gt;In Safari 2, though, the body's offset gets counted twice for absolutely-positioned elements that are direct children of body. Something you don't just guess, you need the thousands of test cases I mentioned earlier to discover something like that...&lt;/P&gt;
&lt;P&gt;In both Safari and Firefox, you must subtract to the coordinates the scroll positions of all &lt;STRONG&gt;parent nodes&lt;/STRONG&gt; (and not the offset parents like before). Well, except if the element is absolutely positioned (this last restriction doesn't apply to Opera). Or if the parent is the body or html element. Confused yet? Wait, there's more.&lt;/P&gt;
&lt;P&gt;In Firefox, non-absolutely positioned elements that are direct children of body get the body offset counted twice.&lt;/P&gt;
&lt;P&gt;In both IE and Firefox (but you don't care for IE as it has &lt;A href="http://msdn2.microsoft.com/en-us/library/ms536433.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms536433.aspx"&gt;getBoundingClientRect&lt;/A&gt;), the border of a table gets counted in both the border of the table and in the td's offset.&lt;/P&gt;
&lt;P&gt;Finally, on Opera, there are scroll values on elements that are not scrolled so you need to explicitly check for the overflow mode before you subtract scroll positions. Opera also includes the scrolling into the offsets, except for positioned contents.&lt;/P&gt;
&lt;P&gt;The worst part in all this is that we don't even know for sure that we nailed it, and we know that future browsers will require adjustments.&lt;/P&gt;
&lt;P&gt;Speaking of which... &lt;A href="http://developer.mozilla.org/en/docs/DOM:element.getBoundingClientRect" mce_href="http://developer.mozilla.org/en/docs/DOM:element.getBoundingClientRect"&gt;Firefox 3 will implement getBoundingClientRect&lt;/A&gt;. I haven't tried &lt;A href="https://bugzilla.mozilla.org/show_bug.cgi?id=174397" mce_href="https://bugzilla.mozilla.org/show_bug.cgi?id=174397"&gt;their implementation&lt;/A&gt; yet and checked whether it has the IE quirks, but it should be a lot simpler than what we have to work around today to do the same thing and we'll definitely have to rely on less undocumented quirks. By the way, if you were thinking of using the undocumented getBoxObjectFor, &lt;A href="https://bugzilla.mozilla.org/show_bug.cgi?id=340571" mce_href="https://bugzilla.mozilla.org/show_bug.cgi?id=340571"&gt;forget it, it was designed for XUL elements and will probably get removed from non-XUL elements in future versions&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;There is &lt;A href="http://bugs.webkit.org/show_bug.cgi?id=15897" mce_href="http://bugs.webkit.org/show_bug.cgi?id=15897"&gt;a bug open against WebKit to get that in Safari but it's currently without an owner&lt;/A&gt;. Here's to hoping this gets into the next version. Vote for it.&lt;/P&gt;
&lt;P&gt;Opera apparently also &lt;A href="http://www.opera.com/docs/changelogs/windows/950b1/index.dml" mce_href="http://www.opera.com/docs/changelogs/windows/950b1/index.dml"&gt;implements that in 9.5&lt;/A&gt;, referencing a &lt;A href="http://dev.w3.org/csswg/cssom/Overview.html#elementlayout-getclientrects" mce_href="http://dev.w3.org/csswg/cssom/Overview.html#elementlayout-getclientrects"&gt;W3C draft&lt;/A&gt; which curiously doesn't contain any references to getBoundingClientRect.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5673801" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/bleroy/archive/tags/Atlas/default.aspx">Atlas</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Microsoft+AJAX+Library/default.aspx">Microsoft AJAX Library</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/HTML/default.aspx">HTML</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Safari/default.aspx">Safari</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Opera/default.aspx">Opera</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Internet+Explorer/default.aspx">Internet Explorer</category><category domain="http://weblogs.asp.net/bleroy/archive/tags/Firefox/default.aspx">Firefox</category></item></channel></rss>