<?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>alert debugging &#187; Cappuccino</title>
	<atom:link href="http://www.alertdebugging.com/category/cappuccino/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alertdebugging.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 05 Nov 2009 11:50:40 +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>Mockingbird, Cappuccino, and what really matters.</title>
		<link>http://www.alertdebugging.com/2009/11/04/mockingbird-cappuccino-and-what-really-matters/</link>
		<comments>http://www.alertdebugging.com/2009/11/04/mockingbird-cappuccino-and-what-really-matters/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 22:23:46 +0000</pubDate>
		<dc:creator>tolmasky</dc:creator>
				<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.alertdebugging.com/?p=327</guid>
		<description><![CDATA[I found an interesting critique via daring fireball regarding the latest Cappuccino application, Mockingbird. I&#8217;m really glad this has come up because I think the concerns are valid and I&#8217;m excited that we can start having a conversation about this. One comment in particular really stuck out for me:

If you load the app, you can [...]]]></description>
			<content:encoded><![CDATA[<p>I found an <a href = "http://groovymother.com/2009/nov/04/mocking2-bird/">interesting critique</a> via <a href = "http://daringfireball.net/linked/2009/11/04/begbie-mockingbird">daring fireball</a> regarding the latest Cappuccino application, <a href="http://gomockingbird.com/">Mockingbird</a>. I&#8217;m really glad this has come up because I think the concerns are valid and I&#8217;m excited that we can start having a conversation about this. One comment in particular really stuck out for me:</p>
<blockquote><p>
If you load the app, you can see custom scrollbars and navigation, a complete lack of accessibility, non-native controls, and all those other things that cause geeks to hate Flash.
</p></blockquote>
<p>This is a classic programmer&#8217;s misunderstanding of a design problem. Listen carefully guys: pure native controls aren&#8217;t what matters. What users <b>actually</b> care about is <b>broken</b> and <b>ugly</b> controls. This should be incredibly obvious from the fact that many of the most popular applications on the Mac use custom &#8220;non native&#8221; controls, such as <a href = "http://www.atebits.com/tweetie-mac/">Tweetie</a>, iTunes, Quicktime, every single Apple Pro App, and <a href = "http://flyingmeat.com/acorn/">Acorn</a> just to name a few. In fact, its almost par for the course now adays.</p>
<p>Now, I haven&#8217;t heard a single complaint that Tweetie for the Mac doesn&#8217;t have blue aqua scrollbars. Why? Because the Tweetie scrollbars work well in this setting and look good. The reason people hated Java&#8217;s UI&#8217;s wasn&#8217;t because they were &#8220;non native&#8221;, its because they were ridiculously horrendous and behaved poorly to boot. Instead of admitting that what was needed was good designers, programmers simply drew the lazy conclusion that every control had to be drawn by the system to give it some sort of magical properties. This is exactly the problem with Flash. What frustrates me about the scrollers in Balsamiq isn&#8217;t simply that they&#8217;re different, its that they don&#8217;t work with my scrollwheel mouse and look incredibly out of place.</p>
<p>In Cappuccino we&#8217;ve taken two important steps: First, we&#8217;ve relentlessly implemented all the &#8220;native&#8221; features of scrollers (and other controls of course) people have come to expect: from command+clicking in the track to respecting horizontal scroll to listening to arrow keys. Have we missed one? Perhaps, in which case you should <a href = "http://github.com/280north/cappuccino/issues">file a bug</a>. Or better yet, <a href="http://github.com/280north/cappuccino">fork the project</a> and ship your fix immediately to your users, something you can&#8217;t do with Flash or the built in controls in HTML. Secondly, we&#8217;ve hired a real design firm, <a href="http://madebysofa.com">Sofa</a>, to make a UI that truly looks awesome on the web: <a href = "http://github.com/280north/aristo">Aristo</a>. You should take a look at their Cappuccino application EnStore and try to argue that this thing doesn&#8217;t feel great:</p>
<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/w-H2dLdZGeM&#038;hl=en&#038;fs=1&#038;rel=0&#038;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/w-H2dLdZGeM&#038;hl=en&#038;fs=1&#038;rel=0&#038;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="394"></embed></object></p>
<p>The second assertion was the following:</p>
<blockquote><p>
Gruber’s definition of “true web app” and mine greatly differ. Clue: If it’s completely unusable on the iPhone Safari browser, it doesn’t matter if it’s built in JavaScript, Flash or Microsoft Visual Fortran 2012. It’s not a “true web app”
</p></blockquote>
<p>Well, for starters:</p>
<div id="attachment_334" class="wp-caption aligncenter" style="width: 330px"><img src="http://www.alertdebugging.com/wp-content/uploads/2009/11/IMG_0105.PNG" alt="Mockingbird on the iPhone" title="Mockingbird on the iPhone" width="320" height="480" class="size-full wp-image-334" /><p class="wp-caption-text">Mockingbird on the iPhone</p></div>
<p>But let&#8217;s get to the real issue here, because this is once again a misunderstanding of design vs. programming. HTML, JS, and CSS do not magically create wonderful experiences on every platform they are run. As you can see from the above screenshot, they certainly have the nice side effect of working on said platforms, but if you&#8217;re expecting HTML to somehow handle the subtle and explicit differences between a handheld multitouch peripheral and a desktop application, well then <b>you&#8217;re doing it wrong</b>. These are completely different environments and they require completely different designs and often implementations. The reason mockingbird is &#8220;completely unusable&#8221; on the iPhone despite loading up fine is because it was designed for a large screen. Photoshop written with perfect semantic markup or however you want to define a &#8220;true web app&#8221; won&#8217;t work on a small screen either. Clearly though, the nice side effect of using Cappuccino is that you&#8217;ll at least be able to share common source code between both versions of these apps.</p>
<p>I think the fundamental conclusion here is that people get really hung up on the &#8220;web&#8221; part of web apps, when they should be focusing on the &#8220;app&#8221; part. At the end of the day, you are delivering your customer an experience. I believe that someday all apps will be web apps, and then this will become much clearer. At that point, what will matter in a mobile web app is the mobile part, and what will matter in the desktop web app is the desktop part.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alertdebugging.com/2009/11/04/mockingbird-cappuccino-and-what-really-matters/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>On HTML 5 Drag and Drop</title>
		<link>http://www.alertdebugging.com/2009/08/16/on-html-5-drag-and-drop/</link>
		<comments>http://www.alertdebugging.com/2009/08/16/on-html-5-drag-and-drop/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 04:22:26 +0000</pubDate>
		<dc:creator>tolmasky</dc:creator>
				<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.alertdebugging.com/?p=260</guid>
		<description><![CDATA[HTML 5 is shaping up to be quite an impressive step up from the capabilities web developers are currently constrained to. One of my favorite new features provided by the spec is support for native drag and drop. Cappuccino and many other JavaScript libraries have had drag and drop support for quite a while now, [...]]]></description>
			<content:encoded><![CDATA[<p>HTML 5 is shaping up to be quite an impressive step up from the capabilities web developers are currently constrained to. One of my favorite new features provided by the spec is support for native drag and drop. <a href = "http://cappuccino.org/learn/tutorials/scrapbook-tutorial-2/">Cappuccino</a> and many other JavaScript libraries have had drag and drop support for quite a while now, but with one important caveat: the drag operations were limited to <b>within</b> the browser window. This was not only visually displeasing, but prevented you from being able to share data in a user friendly way from one web app to another, or even to other desktop apps.  HTML 5 aims to change all this by giving us access to the computer&#8217;s native drag system and clipboard. I took the last week to really familiarize myself with this API and its various implementations on current browsers so I could start adding support for it in Cappuccino. I feel that this gave me a pretty unique perspective on the current state of this feature which I&#8217;d like to share, mainly because I&#8217;ve had to make it work in a number of real (sometimes shipping) applications, as opposed to simplying creating small demos. The good news is that last night I was able to land my first <a href = "http://github.com/280north/cappuccino/commit/e8dd56bda70eb43a3be191e561f15f7674cd57f9">commit</a> which adds full HTML 5 drag and drop support for Safari and other WebKit-based browsers. Here is a short movie that shows this feature in action in our internal <a href = "http://280slides.com">280 Slides</a> builds:</p>
<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Tg6okHlWwv0&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Tg6okHlWwv0&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center></p>
<p>As you can see, this feature enables you to easily share data, whether it be images and shapes or full slides, from one presentation to another. What&#8217;s particularly cool about this is that you won&#8217;t have to change your existing code at all since Cappuccino simply detects when you are on a compliant browser and magically &#8220;upgrades&#8221; to native drag and drop. On older browsers, you will still get the old in-browser implementation. Ah, the beauty of abstraction.</p>
<p>This isn&#8217;t to say that working with this feature was all peaches and cream though. For starters, this feature is far from complete in any browser. I experienced a tremendous amount of bugs, crashes, and inconsistencies in all the browsers I tried. On the one hand, I got to play with a very exciting new toy, and on the other I was given a glimpse into the future of the bugs I would be dealing with for years to come (just when we thought the whole cross-browser thing was starting to become managable). This isn&#8217;t surprising of course, it is a very new addition and the spec isn&#8217;t even 100% complete yet. For this reason, I&#8217;ve decided to split this post up into two pieces. In the following I will be discussing what I believe to be actual and serious design flaws in the current API, as well as a few suggestions I have for how they might be remedied. I will also <a href = "http://www.alertdebugging.com/drag-and-drop-bugs/">separately link</a> to a page that has all the bugs and inconsistencies I discovered (as well as the associated tickets I filed on them), and workarounds when I could find them.</p>
<p>I believe the main &#8220;theme&#8221; of the problems I encountered was due to the fact that I am trying to build full-blown applications as opposed to dynamic web pages. This however is no excuse, as one of HTML 5&#8217;s supposed goals is to usher in an era of more web apps that are more competitive with desktop apps. This is precisely why Google is supporting it so heavily.</p>
<h2>Lazy Data Loading</h2>
<p>One of the key facilities of drag and drop is the ability to provide, and get, multiple representations of the same data. Different web pages, web apps, and desktop apps support different kinds of data, so it is up to your application to give them something they can work with. Take 280 Slides for example: When a user drags the slides out of slides navigator, he may be planning to drop it to any number of locations. If he is dragging it from one instance of 280 Slides to another, then we want to provide a serialized version of these slides so that they can be added to the other presentation. If however, he drags these slides into a program like Photoshop, then we would want to provide image data. If he were to drag them to his desktop, then perhaps we could provide a PDF version. He could even drag them to his text editor and expect the text contents of his slides to be pasted.<br />
<div id="attachment_283" class="wp-caption aligncenter" style="width: 418px"><img src="http://www.alertdebugging.com/wp-content/uploads/2009/08/dragdata.png" alt="Multiple Data Types" title="Multiple Data Types" width="408" height="505" class="size-full wp-image-283" /><p class="wp-caption-text">Multiple Data Types</p></div></p>
<p> The way you do this currently is with the setData function, which allows you to specify different types of data:</p>
<pre class="textmate-source"><span class="source source_js source_js_objj"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>dragstart<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="support support_class support_class_js">event</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
   <span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>dataTransfer<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>setData<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>image/png<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>slides<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>imageRep<span class="meta meta_brace meta_brace_round meta_brace_round_js">())</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
   <span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>dataTransfer<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>setData<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>slides<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>slides<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>serializedRep<span class="meta meta_brace meta_brace_round meta_brace_round_js">())</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
   <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> etc.
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span></span></pre>
<p>This is incredibly common on the desktop, and you&#8217;ve probably never noticed it precisely because it works so well: things seem to just do the right thing when you drag and drop them. However, an unfortunate side effect of this feature is that you end up doing a lot of extra unecessary work. The user only ever drops the item to <b>one</b> location, and so all the other formats you&#8217;ve created were wasted processing time. This is not a big deal for simple cases of drag and drop, but it becomes quite noticable in large applications like 280 Slides. In the example above, creating serialized and image representations of these slides can become quite slow depending on how many elements are in the individual slides and how many slides you are moving. Because of this you may experience a lag when you first drag the slides out. The worst part is, if all you intended to do was reposition the slides in the same presentation, then you didn&#8217;t need any of these formats!</p>
<p>This problem was solved in a very simple and intelligent way on the desktop a long time ago: simply delay supplying the actual data until the drop occurs. At the point of the drop, you actually know which of the 5 supplied types the user is interested in, so create it then. Not only does this save you from doing uncessary work, but generally users notice time spent processing after a drop a lot less (because there is no expected user feedback to stutter). I&#8217;ve thought a lot about a good way to allow the user to do this with the existing setData method , and I think it could be done by simply  allowing developers to provide functions that could be called when the data is needed:</p>
<pre class="textmate-source"><span class="source source_js source_js_objj"><span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>dataTransfer<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>setData<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>slides<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
   <span class="keyword keyword_control keyword_control_js">return</span> costlySerialization<span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p>Perhaps a more backwards compatible alternative would be:</p>
<pre class="textmate-source"><span class="source source_js source_js_objj"><span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>dataTransfer<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>setData<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>slides<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="meta meta_function meta_function_json meta_function_json_js"><span class="entity entity_name entity_name_function entity_name_function_js">toString</span>: <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
   <span class="keyword keyword_control keyword_control_js">return</span> costlySerialization<span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p>Although I don&#8217;t really think this is necessary since this API is so new.  Either way, this allows us to use the existing setData method, while not actually needing to calculate the string value until getData is actually called by the drop target.</p>
<h2>Initiating Drags</h2>
<p>Another major hurdle I encountered was in controling the way drags are actually started. Currently this is a delicate dance of preventDefaults and interactions between mousedown, mousemove, and dragstart, in combination with the draggable HTML attribute. The basic problem with this is that it leaves the decision to create a drag entirely to the the browser. Again, this is just fine for simple cases, but it really starts to break down when you are building full on applications in the browser. On the other hand, frameworks like Cocoa allow the developer to initiate the actual drag sequence. Lets look at why this is important with a simple example. It is quite common to want to start a drag event on the initial mouse down, instead of waiting for additional mouse move events. In these cases, it would be more confusing if the initial mouse down did nothing. This is currently impossible to achieve with the HTML 5 drag and drop APIs. In Cocoa, this would be quite simple, requiring the developer simply start the process in mouseDown: instead of mouseDragged:</p>
<pre class="textmate-source"><span class="source source_objc">- (<span class="storage storage_type storage_type_c">void</span>)mouseDown:(<span class="support support_class support_class_cocoa">NSEvent</span> *)anEvent
<span class="meta meta_block meta_block_c">{
   <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="support support_class support_class_cocoa">NSView</span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">dragImage<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span>myImage <span class="comment comment_block comment_block_c"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_c">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_c">*/</span></span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
}</span></span></pre>
<p>This is just a simple example of course. More complex widgets provide even more cases where drag and drop in the browser really works against you. Take tables in Mac OS X, which provide different behaviors depending on what direction the users drags in:</p>
<p><center><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/KR0TdwObWPs&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/KR0TdwObWPs&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></center></p>
<p>As you can see, when a user drags upwards in a table on Mac OS X, the selection of the table changes (in other words, no drag takes place). On the other hand, if the user drags left, right, or diagonally in any way, then he is allowed to move these files. This is very intuitive experience when you use it, and is absolutely trivial to implement in Cocoa:</p>
<pre class="textmate-source"><span class="source source_objc">- (<span class="storage storage_type storage_type_c">void</span>)mouseDragged:(<span class="support support_class support_class_cocoa">NSEvent</span> *)anEvent
<span class="meta meta_block meta_block_c">{
   <span class="keyword keyword_control keyword_control_c">if</span><span class="meta meta_initialization meta_initialization_c"> <span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_c">(</span></span>deltaX &gt; <span class="constant constant_numeric constant_numeric_c">10</span>)
       <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="support support_class support_class_cocoa">NSView</span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">dragIamge<span class="punctuation punctuation_separator punctuation_separator_arguments punctuation_separator_arguments_objc">:</span></span>myImage <span class="comment comment_block comment_block_c"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_c">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_c">*/</span></span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
   <span class="keyword keyword_control keyword_control_c">else</span>
       <span class="meta meta_bracketed meta_bracketed_objc"><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_begin punctuation_section_scope_begin_objc">[</span><span class="variable variable_language variable_language_objc">self</span> <span class="meta meta_function-call meta_function-call_objc"><span class="support support_function support_function_any-method support_function_any-method_objc">modifySelection</span></span><span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_end punctuation_section_scope_end_objc">]</span></span>;
}</span></span></pre>
<p>However, this is again basically impossible with the current HTML 5 API, as you can never be a part of the decision as to whether an object is dragged or not. Once you get the drag event, it&#8217;s too late. You can imagine that this would become even more cumbersome in applications like <a href = "https://bespin.mozilla.com/">Bespin</a> that revolve less around specific tags and more around content that is drawn to a canvas elements. When a user drag in Bespin, they have to decide between any number of actions. I think a good solution to this would be to simply allow the developer to manually kick off a dragging event loop from either a mousedown or mousemove callback. Something like this:</p>
<pre class="textmate-source"><span class="source source_js source_js_objj"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>mousedown<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="support support_class support_class_js">event</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
   <span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>startDrag<span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

<span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>mousemove<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="support support_class support_class_js">event</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
   <span class="keyword keyword_control keyword_control_js">if</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span>someCondition<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
       <span class="support support_class support_class_js">event</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>startDrag<span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p>In both these cases, calling startDrag would result in no further mousemoves/mouseups being fired in this event loop, and instead would kick off the drag event loop with a &#8220;dragstart&#8221; event. A matching cancelDrag() could be provided as well. This would allow you to cancel a <b>drag</b>, but not any other specific behavior such as selection. Currently calling preventDefault cancels <b>both</b> drags and selection. This actually leads to a number of other confusing results. For example, if you place a textfield within a draggable element, it is essentially impossible for text selection to happen in that textfield, even if you set the textfield itself to not be draggable.</p>
<h2>Drag Images</h2>
<p>One of the nice parts about drag and drop is that you are allowed to set any arbitrary image or element as what is actually rendered during the drag process with the setDragImage method:</p>
<pre class="textmate-source"><span class="source source_js source_js_objj">dragEvent<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>dataTransfer<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>setDragImage<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span>aDOMElement<span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>offsetX<span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>offsetY<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p>However, on Firefox it is required that this element already be visible. Now, I wasn&#8217;t sure whether to list this as simply a bug in Firefox or an actual design flaw, but I chose to list it as a flaw because <a href = "https://developer.mozilla.org/En/DragDrop/DataTransfer">the documentation at mozilla.org</a> would seem to suggest that they may consider this to be &#8220;correct behavior&#8221;. Safari does not have this restriction, and in fact Firefox even seems to make <a href = "https://developer.mozilla.org/En/DragDrop/Drag_Operations#dragfeedback">an exception for canvas elements</a>. Firefox seems particularly strict about this requirement too, as I tried positioning an element offscreen in a negative position, setting its visibility to hidden, setting the display to none, and even placing the element in an offscreen iframe, <b>anything</b> to prevent having to actually flash the element in some random portion of the screen before dragging it. It seems to me that this method exists for the purpose of showing something <b>different</b>, and thus it&#8217;s a bit unreasonable to expect it to already be not only in the document, but visible as well. My request here is simple: that it should simply work the way it does in Safari.</p>
<h2>Conclusion</h2>
<p>Drag and drop is an incredibly important part of the way we interact with computers, which is why it is so crucial that we get it right from the beginning. I really hope my concerns are heard and that we can come up with some good solutions to the initial problems I faced with this young API, so that we can avoid the windows of incompatibility that plagued the last updates to HTML. In the meanwhile, I&#8217;ve filed a bunch of bugs and documented my current experiences <a href = "http://www.alertdebugging.com/drag-and-drop-bugs/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.alertdebugging.com/2009/08/16/on-html-5-drag-and-drop/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Building a Better JavaScript Profiler with WebKit</title>
		<link>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/</link>
		<comments>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 20:14:13 +0000</pubDate>
		<dc:creator>tolmasky</dc:creator>
				<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Objective-J]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://www.alertdebugging.com/?p=18</guid>
		<description><![CDATA[I had the pleasure of showing off some the cool new features we&#8217;ve been adding to the WebKit inspector at JSConf last week. It&#8217;s no secret that debugging basically sucks in JavaScript, and until recently, it was a little bit worse in Objective-J. Up until now we&#8217;ve focused mainly on adding stop gap measures to [...]]]></description>
			<content:encoded><![CDATA[<p>I had the pleasure of showing off some the cool new features we&#8217;ve been adding to the WebKit inspector at <a href="http://www.jsconf2009.com/">JSConf</a> last week. It&#8217;s no secret that debugging basically sucks in JavaScript, and until recently, it was a little bit worse in <a href="http://cappuccino.org">Objective-J</a>. Up until now we&#8217;ve focused mainly on adding stop gap measures to our own code, but recently we&#8217;ve decided to shift gears and attack the problem head on in the browsers themselves. This is why these past couple of weeks I&#8217;ve set aside the JavaScript code and instead focused on working with the great guys on the WebKit team on providing a solid debugging experience both in Objective-J and JavaScript in general. We first decided to focus on profiling, since this is an area of considerable interest for a framework. All the code I&#8217;ve committed is now available in the latest WebKit nightly, so if you want you can <a href="http://nightly.webkit.org/">download</a> it to follow along. I&#8217;ve also added to the end of this post links to both the WebKit commits we added, as well as the accompanying code we put in Cappuccino in an effort to show how to make the best use of these new features and encourage others to take a stab at adding some debugging features to WebKit. Surprisingly enough, the folks over at <a href="http://joose-js.blogspot.com/">Joose</a> wasted no time incorporating this into their own library, so I&#8217;ve included links to their additions as well.</p>
<h2>Anonymous and Poorly Named Functions</h2>
<p>Had you run a Cappuccino application through Firebug&#8217;s profiler back in September when we originally open sourced the framework, you would have probably seen something that looked like this:</p>
<div id="attachment_44" class="wp-caption aligncenter" style="width: 387px"><img class="size-full wp-image-44" title="Anonymous Functions in Firebug" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/firebug-anonymous.png" alt="Anonymous Functions in Firebug" width="377" height="252" /><p class="wp-caption-text">Anonymous Functions in Firebug</p></div>
<p>Anyone who&#8217;s done a significant amount of profiling with Firebug has probably run into the dreaded question mark functions at some point or another, but as you can see from above, it used to be particularly egregious in Objective-J. The reason these question marks show up is because somewhere the script in question contains an <strong>anonymous function</strong>. Anonymous functions, or lambdas as they&#8217;re sometimes referred to, are functions that you can declare just about anywhere in your program and not bother naming. Take the following code for example:<br />
<!-- First Code Snippet --></p>
<pre class="textmate-source"><span class="source source_js"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>click<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="comment comment_block comment_block_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">*/</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!-- End First Code Snippet --></p>
<p>Here we&#8217;re using an anonymous function to perform special behavior on a mouse click event, and when profiled, this function will show up as a question mark. The obvious workaround is to simply declare this function normally somewhere else in the code, but this isn&#8217;t always possible because you might need it inline in the code so as to form a closure. So instead the recommended solution today is to simply give it a name with the following syntax:</p>
<p><!--Second Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>click<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">clicked</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="comment comment_block comment_block_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">*/</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!--End Second Code Snippet-->And in this particular case, this will work quite well and allow this function to appear in profile as <span class="inline-code">clicked</span>. However, there are certain cases where this won&#8217;t work. Let&#8217;s look at a different snippet of code to see such a case:</p>
<p><!-- Third Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="keyword keyword_control keyword_control_js">return</span> <span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!-- End Third Code Snippet-->Here we&#8217;ve created a function called <span class="inline-code">generator</span> that creates other functions when executed. As is, these functions will show up as question marks just as before, but this time we can&#8217;t simply name them inline because then <strong>all</strong> the generated functions would show up with the exact same name:<br />
<!-- Fourth Code Snippet --></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="keyword keyword_control keyword_control_js">return</span> <span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">iterate</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!-- End Fourth Snippet-->Unfortunately, there is really very little we can do to remedy this situation short of using an eval statement, which would change the performance characteristics of this method so drastically that the entire exercise would become moot. It&#8217;s not just floating anonymous functions that suffer from poor naming though. Imagine that you have created the following prototypal classes and methods in your application or library:<br />
<!--Fifth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Fifth Code Snippet-->Both in Firebug and Safari, this code will generate a largely useless profile:</p>
<div id="attachment_113" class="wp-caption aligncenter" style="width: 387px"><img class="size-full wp-image-113" title="Profiling object methods in Firebug or Safari" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-12-copy1.png" alt="Profiling object methods in Firebug or Safari" width="377" height="165" /><p class="wp-caption-text">Profiling object methods in Firebug or Safari</p></div>
<p>This profile is almost as ambiguous as when it was all question marks. We can&#8217;t tell whether <span class="inline-code">MyClass.myMethod</span>, <span class="inline-code">MyClass.prototype.myMethod</span>, or <span class="inline-code">MyOtherClass.prototype.myMethod</span> is the bottleneck here. If we aren&#8217;t generating these methods in any special way, we could try to name them inline, but we&#8217;d have to mangle the names considerably to pack in all the information we need:<!--Sixth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js">MyClass<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_dom support_constant_dom_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyClass__class__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyClass__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyOtherClass__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Sixth Code Snippet-->This is clearly not the most elegant solution, and doesn&#8217;t scale given the fact that you have limited visual room in Firebug and Safari (you actually can&#8217;t stretch the function name column in either profiler). This also runs the risk, albeit a small one, of clashing with an existing function name. But the important thing to notice here is that it is not necessarily anonymous functions that are the source of the problem, but the fact that functions don&#8217;t <strong>actually</strong> have real names in JavaScript. It is only the variables that are bound to them that are named. So in order to solve this issue once and for all, we decided to define a way to explicitly give functions a name for debugging: the <strong>displayName</strong> attribute. In WebKit, you can now simply set this property with any arbitrary name you desire. Let&#8217;s revisit our <span class="inline-code">generator</span> example from earlier and see what we can do with this slightly modified code:<br />
<!--Seventh Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="storage storage_type storage_type_js">var</span> <span class="meta meta_function meta_function_js"><span class="entity entity_name entity_name_function entity_name_function_js">generated</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

    generated<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>displayName <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>iterating <span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span> <span class="keyword keyword_operator keyword_operator_js">+</span> iterations <span class="keyword keyword_operator keyword_operator_js">+</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span> times<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

    <span class="keyword keyword_control keyword_control_js">return</span> generated<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Seventh Code Snippet--><br />
If we now rerun this profile in a recent WebKit nightly, we should see something like this:</p>
<div id="attachment_104" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-104" title="Explicitly named functions in WebKit Profiles" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/untitled-4.png" alt="Explicitly named functions in WebKit Profiles" width="516" height="184" /><p class="wp-caption-text">Explicitly named functions in WebKit Profiles</p></div>
<p>Each function is now clearly identifiable in the results, allowing us to actually make use of this data. We can extend this same approach to our prototypal classes we defined above to achieve a similar effect:<br />
<!--Eighth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

MyClass<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_dom support_constant_dom_js">method</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>displayName <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyClass.method (class)<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method.displayName</span> <span class="keyword keyword_operator keyword_operator_js">=</span> </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyClass.method<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method.displayName</span> <span class="keyword keyword_operator keyword_operator_js">=</span> </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyOtherClass.method<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!--End Eighth Code Snippet-->If we were to profile this now, the much more descriptive displayNames would show up instead of simply seeing <span class="inline-code">method()</span> used in every case. This is the basic idea behind what Objective-J does in the latest Cappuccino 0.7 betas, but it takes place completely automatically behind the scenes, so that with no code changes of your own, applications now look something like this when profiled:</p>
<div id="attachment_102" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-102" title="Profiling Objective-J in WebKit" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-82.png" alt="Profiling Objective-J in WebKit" width="516" height="313" /><p class="wp-caption-text">Profiling Objective-J in WebKit</p></div>
<p>As you can see from this profile, Objective-J now has first class profiling support in WebKit. The best part about this though is that it&#8217;s not just limited to Objective-J: any language abstraction now has the opportunity to make the same use of these tools. Objective-J happens to be a great candidate because it is such a thin wrapper around JavaScript, but a project such as processing.js could show the actual processing functions instead of their generated JavaScript analogues, or perhaps GWT could have a flag where it shows the Java methods in the profiler instead of the generated JavaScript as well. We&#8217;ve actually taken this one step further in Objective-J though, and used this feature to display information that you actually can&#8217;t presently see with normal JavaScript scripts. Currently both Safari and Firebug are incapable of profiling code that doesn&#8217;t execute explicitly in a function. This means that if a good portion of your profile is taking place at the top level of a script file, it will be completely left out in Firebug and lumped into the overly generic <span class="inline-code">(program)</span> category in Safari. But thanks to the special way we handle files in Objective-J, we are able to tell our users precisely how much time they are spending in a specific file:</p>
<div id="attachment_107" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-107" title="Objective-J is smart about files in profiles" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/files.png" alt="Objective-J is smart about files in profiles" width="516" height="186" /><p class="wp-caption-text">Objective-J profiling is smart about files in WebKit</p></div>
<p>This is actually what I found most exciting about this seemingly simple property addition. In less than a day I was able to apply it in a completely new way to supply WebKit with even more information than we had originally designed it for. I feel that there is something really interesting in the idea that the code can interact directly with the debugging tools, and its why I believe that despite the debugging situation being so poor in JavaScript today, it has the potential of being much better than that of traditional languages. Expect to see us experiment more with this new kind of debugging here at <a href="http://280north.com">280 North</a> in the future, because this is clearly just the tip of the iceberg.</p>
<h2>More Fine-Grained Profiling</h2>
<p>The other thing we focused heavily on doing these last couple of weeks was completely rewriting the Bottom Up View of the WebKit profiler. To get a better idea of what this is, lets first take look at the other alternative WebKit currently gives you for analyzing your profiles, known as the Top Down View:</p>
<div id="attachment_147" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-147" title="Top Down View in WebKit" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/tree-view.png" alt="Top Down View in Safari" width="516" height="177" /><p class="wp-caption-text">Top Down View in WebKit</p></div>
<p>The Top Down View shows you a graph of the actual flow of your application, a call stack with the very first functions that were executed as the root nodes and the functions they called as their children. Thus, the data in each row represents the statistics for the call stack starting with the root node, and ending in the child node. I&#8217;ve fully expanded all the nodes here to be able to see the entire call graph. If we look at the second to last line of this view, we can see that it represents a recursive call to <span class="inline-code">aFunction</span> that took place from within a call to <span class="inline-code">caller3</span>:</p>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 464px"><img class="size-full wp-image-186" title="Call stack represented in Top Down View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-9.png" alt="Call stack represented in Top Down View" width="454" height="137" /><p class="wp-caption-text">Call stack represented in Top Down View</p></div>
<p>We&#8217;d read this by saying that 0.41% of the time was spent in 5 calls to <span class="inline-code">aFunction</span> with this call stack. While this representation of your profile certainly gives you a very holistic view of what happened in your program and can help you get a better idea of the general flow of functions taking place, it&#8217;s harder to draw conclusions such as which function most of the time is being spent in. To do this, we would need to add up all the individual child times and then compare them to eachother. In this simple example this doesn&#8217;t seem that daunting, but you can imagine that it can quickly become quite complex.</p>
<p>This is where the Bottom Up View comes in. Let&#8217;s take a look at the same profile using this view:</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-143" title="Bottom Up View Collapsed" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/heavy-collapsed.png" alt="Bottom Up View Collapsed" width="516" height="177" /><p class="wp-caption-text">Bottom Up View Collapsed</p></div>
<p>If we leave the children collapsed, this should look very familiar to Firebug users: it is a flat list of every function called in your program, and how much time was spent in each. However, where things really get interesting is when you expand the children:</p>
<div id="attachment_144" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-144" title="Bottom Up View Expanded" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/heavy-expanded.png" alt="Bottom Up View Expanded" width="516" height="177" /><p class="wp-caption-text">Bottom Up View Expanded</p></div>
<p>Unlike in the Top Down View, the children here represent the parents, or callers, of the root function in question. For example, the second row represents the call stack <strong>starting</strong> at <span class="inline-code">caller3</span> and <strong>ending</strong> at <span class="inline-code">aFunction</span>:</p>
<div id="attachment_187" class="wp-caption aligncenter" style="width: 296px"><img class="size-full wp-image-187" title="The call stack represented in the Bottom Up View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-10.png" alt="The call stack represented in the Bottom Up View" width="286" height="125" /><p class="wp-caption-text">The call stack represented in the Bottom Up View</p></div>
<p>Because of this, the statistics on each row actually still refer to the original root node, and not the child as in the Top Down View. So on the second row you&#8217;d say &#8220;1000 calls to aFunction took place <strong>originating from</strong> caller3&#8243;. Essentially we are just flipping the Top Down View on its head. In order to understand why this information is so powerful, let&#8217;s take a look at a real world example I recently ran into in Cappuccino. Now, the following is an Objective-J profile, but the principles are exactly the same in normal JavaScript:</p>
<div id="attachment_133" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-133" title="Objective-J Profile in Bottom Up View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/collapsed.png" alt="Objective-J Profile in Bottom Up View" width="516" height="313" /><p class="wp-caption-text">Objective-J Profile in Bottom Up View</p></div>
<p>If we were using Firebug or any other flat listing tool, the naive interpretation of this profile would be that <span class="inline-code">setFrameSize:</span> is probably something worth tuning since it is third on our list and takes about 4.58% of our profile&#8217;s total time. This diagnosis is not wrong in the strict sense, but we may find it difficult to find out exactly why this method is so slow if we simply jump into <span class="inline-code">setFrameSize:</span>&#8217;s implementation and start hacking away.  Remember that functions can be quite complex internally as well, and you may spend your time needlessly optimizing a code path in this method that was not even reached during the profile. However, we may get a better idea if we instead inspect this further and look at <span class="inline-code">setFrameSize:</span>&#8217;s callers:</p>
<div id="attachment_138" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-138" title="Examining setFrameSize:'s callers" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/expanded1.png" alt="Examining setFrameSize:'s callers" width="516" height="313" /><p class="wp-caption-text">Examining setFrameSize:</p></div>
<p>Interestingly enough, after expanding this node we find that it is not necessarily <span class="inline-code">setFrameSize:</span> which is universally slow, but rather some special interaction between <span class="inline-code">setFrameSize:</span> and its caller <span class="inline-code">sizeToFit</span>. We know this because this method usually takes an average of 0.01% to 0.04%, but specifically when called from <span class="inline-code">sizeToFit</span> it takes a whopping 4.34%, over 200 times as long. Not only that, but all this time is concentrated in just 1 actual call, profiling gold! Perhaps there is something in <span class="inline-code">sizeToFit</span> that is purging a cache that <span class="inline-code">setFrameSize:</span> relies on, or perhaps <span class="inline-code">sizeToFit</span> causes <span class="inline-code">setFrameSize:</span> to take a completely different code path internally than normal. It could be any number of reasons, but we are now empowered with a much better understanding of what exactly is happening in the program that is causing this slowdown. In other words, this allows us to profile not only the functions themselves, but the relationship between functions as well.</p>
<h2>What&#8217;s Next?</h2>
<p>Debugging in JavaScript still has a long way to go. These changes are like night and day for frameworks like Cappuccino, but we have a bunch of other ideas we&#8217;d like to get implemented in WebKit&#8217;s inspector as well. We also think its important to try to take some of the work we&#8217;ve done here and get it placed into Firebug. Given that there is no one browser your code will run in, it is important to have a great set of tools on as many browsers as possible. We&#8217;ve used a hacked version of Firebug internally before, and if I recall correctly it shouldn&#8217;t be too difficult to add support for the displayName property to function objects, so hopefully we&#8217;ll get a patch out for that soon.</p>
<h2>Addendum</h2>
<p>As promised earlier, I have included a list of links to the WebKit, Cappuccino, and Joose commits below. The Cappuccino and Joose commits should help you integrate support for these new WebKit features in your own application or library, and hopefully the WebKit commits will inspire you to report/fix/write new features for JavaScript debugging:</p>
<h3>WebKit</h3>
<ul>
<li><a href="http://trac.webkit.org/changeset/42808">Bottom Up View Re-implementation</a></li>
<li><a href="http://trac.webkit.org/changeset/42478">function.displayName property</a></li>
</ul>
<h3>Cappuccino</h3>
<ul>
<li><a href="http://github.com/280north/cappuccino/commit/0e8e725f59daa041ebfed84d7173e39499617e25">Displaying Objective-J methods in the WebKit profiler</a></li>
<li><a href="http://github.com/280north/cappuccino/commit/2f790c650338e235bab0af749a5a11edb3282704">Displaying files in the WebKit profiler</a></li>
</ul>
<h3>Joose</h3>
<ul>
<li><a href="http://code.google.com/p/joose-js/source/detail?r=756#">Support for function.displayName</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
