<?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>Fly together Forever 比翼恒飞</title>
	<atom:link href="http://www.liucougar.net/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.liucougar.net/blog</link>
	<description></description>
	<lastBuildDate>Fri, 19 Feb 2010 21:27:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9-rare</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>&#8220;setting a property that has only a getter error&#8221; Error in FF 3.6</title>
		<link>http://www.liucougar.net/blog/archives/207</link>
		<comments>http://www.liucougar.net/blog/archives/207#comments</comments>
		<pubDate>Fri, 19 Feb 2010 20:12:11 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=207</guid>
		<description><![CDATA[I have been seeing &#8220;setting a property that has only a getter error&#8221; poping up in my firebug for a while, which I believed was a Firefox extension conflict with new version of firebug.
A recent post to dojo-interest mailing list caught my eye: basically, a user can reproduce this problem by just loading dojo from [...]]]></description>
			<content:encoded><![CDATA[<p>I have been seeing &#8220;setting a property that has only a getter error&#8221; poping up in my firebug for a while, which I believed was a Firefox extension conflict with new version of firebug.</p>
<p>A recent <a href="http://n3.nabble.com/Getting-error-setting-a-property-that-has-only-a-getter-when-loading-a-test-page-tp215458p217155.html" target="_blank">post</a> to dojo-interest mailing list caught my eye: basically, a user can reproduce this problem by just loading dojo from google CDN.</p>
<p>I decided to take a look at this and try to figure out why.</p>
<p>A firebug <a href="http://code.google.com/p/fbug/issues/detail?id=2263" target="_blank">bug report</a> is filed about this error: with FireFox&gt;3.5.2, modifying window.console (or attributes on console) would trigger this error. However, in the test case mentioned in the post, even if dojo is not loaded, the error still pops up in firebug, so it must be in some firefox extension, rather than dojo.</p>
<p>The only other extension I have in my development firefox profile is Selenium-IDE 1.0.4. Disabling it, and the error immediately goes away. Searching selenium-ide bug report, it <a href="http://code.google.com/p/selenium/issues/detail?id=363" target="_blank">turns out</a> it has just been fixed in <a href="http://release.seleniumhq.org/selenium-ide/1.0.5/selenium-ide-1.0.5.xpi" target="_blank">Selenium-IDE 1.0.5</a> (direct link to the xpi file).</p>
<p>In a summary, if you are getting &#8220;setting a property that has only a getter error&#8221; Error in FF 3.6 with any page, make sure you have at least Selenium-IDE 1.0.5. If you don&#8217;t use it, then you are probably messing around with window.console. (the error message would be much more helpful if it states what property is being accessed)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/207/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bug fixes and a new feature in DOH</title>
		<link>http://www.liucougar.net/blog/archives/186</link>
		<comments>http://www.liucougar.net/blog/archives/186#comments</comments>
		<pubDate>Mon, 16 Feb 2009 08:50:47 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=186</guid>
		<description><![CDATA[Over the weekends, I spent some time on Dojo Objective Harness (DOH) to fix a reported bug: in some cases the global progress bar overshoots 100%. This is obvious in the dojo test suite, the progress bar goes beyond 900%.
After some digging, it turns out the algorithm to calculate the global progress bar has a [...]]]></description>
			<content:encoded><![CDATA[<p>Over the weekends, I spent some time on Dojo Objective Harness (DOH) to fix <a href="http://bugs.dojotoolkit.org/ticket/8378">a reported bug</a>: in some cases the global progress bar overshoots 100%. This is obvious in the <a href="http://archive.dojotoolkit.org/dojo-2009-02-15/dojotoolkit/dojo/tests/runTests.html">dojo test suite</a>, the progress bar goes beyond 900%.</p>
<p>After some digging, it turns out the algorithm to calculate the global progress bar has a flawed assumption: the number of tests in each group is known before the tests start. That&#8217;s not the case if nested test suites are used, such as the case in dojo._base.test.</p>
<p>The <a href="http://bugs.dojotoolkit.org/changeset/16684">fix</a> is quite simple as well: rather than trying to create a portion in the global progressbar for each test, we only create one for each group.</p>
<p>Another problem noted in the <a href="http://bugs.dojotoolkit.org/ticket/8378">original bug report</a> is overflow of test group progressbar. I never noticed it before, but keeping a close eye on each group progressbar when running dojo test suite does reveal it. By removing tests in the dojo test suite, I isolated the problem to dojo.date and dojo.date. The problem is the test group progress bar is not updated at all due to the fact that they don&#8217;t have a html page (instead both dojo.date and dojo.data test cases only use javascript files). The <a href="http://bugs.dojotoolkit.org/changeset/16690">fix</a> for this turns out to be quite straghtforward as well as soon as I know what causes it.</p>
<p>After the bug fixes, I feel like to add a new feature to DOH, <a href="http://bugs.dojotoolkit.org/ticket/8653">clickable test cases</a> which will hilight the relevant log line after the test finishes. Searching a failture/error in the log pane is a real pain especially if you have lots of tests generating huge number of messages. The log line will be hilighted according to whether the test failed or succeeded. (Note: the hilighting requires dojo, so if DOH is used without dojo, you won&#8217;t be able to see the hilighting animation.)</p>
<p>Similarly, when clicking on the global progressbar, the test group associated with that portion of the bar will be scrolled into view (for any failed test group, a tooltip is also attached to the global progressbar portion to indicate which test group it is). This is useful when locating a failed test group.</p>
<p>In addition, a tfoot is added to the test list table after all tests finish, which contains a summary of the test run. Check out the <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojo/tests/runTests.html">online demo in our nightly</a>. This will be part of dojo 1.3 release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/186/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switch user interface language in google maps</title>
		<link>http://www.liucougar.net/blog/archives/179</link>
		<comments>http://www.liucougar.net/blog/archives/179#comments</comments>
		<pubDate>Fri, 06 Feb 2009 08:58:21 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=179</guid>
		<description><![CDATA[Apparently, google maps has different features/capacities based on different user interface languages. My parents just complained to me that they can&#8217;t find &#8220;place of interests&#8221; in their google maps any more. After obtaining more information from them, it appears that they are actually using Chinese version of google maps, while when they were using the [...]]]></description>
			<content:encoded><![CDATA[<p>Apparently, google maps has different features/capacities based on different user interface languages. My parents just complained to me that they can&#8217;t find &#8220;place of interests&#8221; in their google maps any more. After obtaining more information from them, it appears that they are actually using Chinese version of google maps, while when they were using the English version, &#8220;place of interests&#8221; was indeed visible as an option.</p>
<p>So the problem is how to change the UI language. The website URL for the Chinese version of google maps is the same as the English version, both of which is maps.google.com, so must be another way of doing it. Searching the UI, I can&#8217;t find a control to change language anywhere. However, I did notice on one page when clicking around, where I have this in my address bar.</p>
<p><a href="http://maps.google.com/maps/mm?hl=en">http://maps.google.com/maps/mm?hl=en</a></p>
<p>by chaning it to:</p>
<p><a href="http://maps.google.com/maps/mm?hl=zh-CN">http://maps.google.com/maps/mm?hl=zh-CN</a></p>
<p>As expected, I get Simplified Chinese version of google maps. So to switch UI language in gmap is to append &#8220;?hl=LANG_CODE&#8221; to the URL, such as:</p>
<p><a href="http://maps.google.com/?hl=en">http://maps.google.com/?hl=en</a></p>
<p>Will load the gmap front page in English. Some LANG_CODE I tried which are recognized by gmap is: de, en, fr, ko, ja, ru, zh-CN and zh-TW. (See <a href="http://www.i18nguy.com/unicode/language-identifiers.html">language identifier</a> for a complete list)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/179/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>librsvg does not support underlined text in svg</title>
		<link>http://www.liucougar.net/blog/archives/166</link>
		<comments>http://www.liucougar.net/blog/archives/166#comments</comments>
		<pubDate>Fri, 02 Jan 2009 23:49:39 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=166</guid>
		<description><![CDATA[It is well known that Firefox (even the latest 3.x) does not support text-decoration=&#8221;underline&#8221; on text elements in SVG. However, it bites me hard when I found out imagemagick does not support that either when rastering svg to pixel images.
After digging around, (by looking at the ebuild file) I found out that imagemagick is actually [...]]]></description>
			<content:encoded><![CDATA[<p>It is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=317196" target="_blank">well known</a> that Firefox (even the latest 3.x) does not support <strong>text-decoration=&#8221;underline&#8221;</strong> on text elements in SVG. However, it bites me hard when I found out imagemagick does not support that either when rastering svg to pixel images.</p>
<p>After digging around, (by looking at the <a href="http://gentoo-portage.com/media-gfx/imagemagick" target="_blank">ebuild</a> file) I found out that imagemagick is actually making use of librsvg to do the heavy lifting when dealing with svg files.</p>
<p>librsvg is part of gnome-base packages (as can be seen in <a href="http://gentoo-portage.com/gnome-base/librsvg" target="_blank">gentoo portage</a>). Looking at the source code, I figured that it makes use of <a href="http://www.pango.org/" target="_blank">pango</a> to render text.</p>
<p>From the days of working on <a href="http://www.scim-im.org/" target="_blank">SCIM</a> project, I know for sure that pango is more than capable of rendering text with underlines. So there must be something missing in librsvg to render it. It turns out that, while the svg parser implemented in librsvg does indeed look for text-decoration, and recoganize underline (among strikethrough and overline), it is not actually making use of these parsed info to render the text.</p>
<p>After a bit of tracing the code, I found out how to patch it: the trick is just to add a pango underline attribute to the text layout, and everything else is taken care of by pango.</p>
<p>This bug is <a href="http://bugzilla.gnome.org/show_bug.cgi?id=566365" target="_blank">reported</a> to upstream, and hopefully it will be merged there soon. The patch is available in that bug report, so you can grab it if you can&#8217;t wait. The patch also fixes a bug which is discovered after the underline problem is fixed: when a underlined text has stroke set, the stroke is rendered in wrong position.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/166/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New column for dijit.Menu: accelerator/shortcut key</title>
		<link>http://www.liucougar.net/blog/archives/155</link>
		<comments>http://www.liucougar.net/blog/archives/155#comments</comments>
		<pubDate>Sun, 28 Dec 2008 09:12:47 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=155</guid>
		<description><![CDATA[In a desktop environmen, menus (be it context menu or menu in menubar) have a column which display the accelerator key (or shortcut key in windows). In the 0.4 dojo Menu widget, we used to have that support, but it was not ported to 1.x.

After seeing Bill&#8217;s commit to add a real MenuBar to dijit, [...]]]></description>
			<content:encoded><![CDATA[<p>In a desktop environmen, menus (be it context menu or menu in menubar) have a column which display the accelerator key (or shortcut key in windows). In the 0.4 dojo Menu widget, we used to have that support, but it was not ported to 1.x.</p>

<p>After seeing <a href="http://dojotoolkit.org/2008/12/26/menubar-and-menu" target="_blank">Bill&#8217;s commit</a> to add a real MenuBar to dijit, I think it&#8217;s the time to bring back this feature. For now, see the <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/test_Menu.html" target="_self">test_Menu.html</a> test file for a demo.</p>

<p>A new property is introduced for dijit.MenuItem, called <code>accelKey</code>, of type <code>String</code>. It can be set either in markup or in the arguments passed to the dijit.MenuItem constructor (the <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/test_Menu.html" target="_blank">demo</a> contains examples for both of them). In addition, dynamically setting it is also supported, such as:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//item is a dijit.MenuItem object</span>
<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;accelKey&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;Ctrl+W&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>



<p>As mentioned in the <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/test_Menu.html" target="_blank">demo</a>, this <code>accelKey</code> is only a string, you can basically pass in any string you want. However, when the combination is pressed, it won&#8217;t actually trigger the action associated with the menu item: that has to be done explicitly elsewhere (such as dojo.connect to body&#8217;s onkeydown event, and detect whether a recognized accelerator key is pressed, if so, invoke the corresponding event handler).</p>]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/155/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lazy loading of dropdown menu in dijit.form.DropDownButton</title>
		<link>http://www.liucougar.net/blog/archives/140</link>
		<comments>http://www.liucougar.net/blog/archives/140#comments</comments>
		<pubDate>Fri, 26 Dec 2008 06:52:51 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=140</guid>
		<description><![CDATA[By default, dijit.form.DropDownButton requires a dropdown menu specified when initializating. However, with a little bit of patching via subclassing it, we can easily achieve lazy loading of the dropdown menu: only creating it the first time a user clicks on the button. This will speed up the initial loading time of the application, especially if [...]]]></description>
			<content:encoded><![CDATA[<p>By default, <a href="http://api.dojotoolkit.org/jsdoc/dijit/trunk/dijit.form.DropDownButton">dijit.form.DropDownButton</a> requires a dropdown menu specified when initializating. However, with a little bit of patching via subclassing it, we can easily achieve lazy loading of the dropdown menu: only creating it the first time a user clicks on the button. This will speed up the initial loading time of the application, especially if a lot of these type of buttons are present on the page.</p>

<p>Here is the core of how to achieve lazy loading:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript javascript" style="font-family:monospace;">dojo.<span style="color: #660066;">declare</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;MyDropDownButton&quot;</span><span style="color: #339933;">,</span> dijit.<span style="color: #660066;">form</span>.<span style="color: #660066;">DropDownButton</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
	dropDown<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>
	_openDropDown<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dropDown</span><span style="color: #339933;">===</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dropDown</span><span style="color: #339933;">=</span><span style="color: #003366; font-weight: bold;">new</span> dijit.<span style="color: #660066;">Menu</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
			<span style="color: #003366; font-weight: bold;">var</span> items<span style="color: #339933;">=</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span>label<span style="color: #339933;">:</span><span style="color: #3366CC;">'One'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>label<span style="color: #339933;">:</span><span style="color: #3366CC;">'Two'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>label<span style="color: #339933;">:</span><span style="color: #3366CC;">'Three'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span>;
			dojo.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span>items<span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dropDown</span>.<span style="color: #660066;">addChild</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> dijit.<span style="color: #660066;">MenuItem</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;    
			<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>;
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">inherited</span><span style="color: #009900;">&#40;</span>arguments<span style="color: #009900;">&#41;</span>;
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>




<p>The trick here is to set dropDown to something which evaluates to true so that when clicked the first time, DropDownButton will proceed to call _openDropDown, where we have a chance to create the real <a href="http://api.dojotoolkit.org/jsdoc/dijit/trunk/dijit.Menu">dijit.Menu</a> we want to show. Without line 2 above, _openDropDown won&#8217;t be called because DropDownButton thinks there is no attached dropdown menu.</p>

<p>As you may have already figured, in order to use this, the Menu has to be created programmatically.</p>]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/140/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copy HTML (RichText) to windows clipboard from Java</title>
		<link>http://www.liucougar.net/blog/archives/92</link>
		<comments>http://www.liucougar.net/blog/archives/92#comments</comments>
		<pubDate>Mon, 22 Dec 2008 01:44:45 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[doh.robot]]></category>
		<category><![CDATA[functional test]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=92</guid>
		<description><![CDATA[While trying to add setting clipboard content support to doh.robot, I encountered a very strange bug and spent several hours of trail and failure without going anywhere. I am using java 1.6 update 11 directly from Sun. Basically, I have two problems both of which are described here: copying HTML data to windows clipboard from [...]]]></description>
			<content:encoded><![CDATA[<p>While trying to add setting clipboard content support to <a href="http://dojotoolkit.org/2008/08/11/doh-robot-automating-web-ui-unit-tests-real-user-events" target="_blank">doh.robot</a>, I encountered a very strange bug and spent several hours of trail and failure without going anywhere. I am using java 1.6 update 11 directly from Sun. Basically, I have two problems both of which are described <a href="http://www.peterbuettner.de/develop/javasnippets/clipHtml/index.html" target="_blank">here</a>: copying HTML data to windows clipboard from java does not work, with the following symptoms</p>
<ol>
<li>when puting data into the clipboard with a <code>RepresentationClass</code> other than <code>java.lang.String</code> does not work properly with any applications (it is the same issue as described in <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6392086" target="_blank">a java bug report</a>, which is supposed to be fixed in java 1.6 update 11)</li>
<li>even if you do use <code>java.lang.String</code> as <code>RepresentationClass</code>, the pasted html only appear correctly in IE, not in safari (it contains extra garbage characters), nor in FF (nothing is pasted at all).</li>
</ol>
<p>The problem as described in the mentioned webpage, is due to buggy support of windows HTML clipboard format in java. One workaround is suggested in the same article by modifying some internal stuffs in the supporting class in java with the source files available for download. However, the provided code fails to run against my java 1.6 (although it does compile fine), probably due to changed internal mechanisms.</p>
<p><span id="more-92"></span>Luckily, I tried to run the same code against the next version of java (1.7 provided by <a href="http://openjdk.java.net/" target="_blank">openjdk</a>, still in development), and the paste works great in all three browsers. However, this java 1.7 does not provide a java plugin for Safari, nor google Chrome. (only java 1.6u10 and 1.6u11 support these two new comers)</p>
<p>In order to workaround this, I decided to backport the fix from java 1.7 to 1.6. I don&#8217;t want to re-compile the whole jre or jdk, I just want to fix this particular bug. The buggy code is in <code>sun/awt/windows/HTMLSupport.class</code> (in rt.jar under java installation folder).</p>
<p>After poking around in the java 1.7 source (grabbed from <a href="http://openjdk.java.net/" target="_blank">openjdk</a>), it turns out that file does not exists. However, with some string searching in files, I found out that it is now defined in <code>jdk\src\windows\classes\sun\awt\windows\WDataTransferer.java</code>. After doing some renaming and such, I came up with a <a href="http://www.liucougar.net/blog/wp-content/uploads/2008/12/htmlsupport.java">HTMLSupport.java</a> source file (which is a direct port of the original file included in java 1.7 source). Aftering <a href="http://www.tedneward.com/files/Papers/BootClasspath/index.html" target="_blank">hijacking</a> the builtin <code>HTMLSupport</code>, sure enough, everything works as expected in java 1.6 now.</p>
<p>A pre-compiled <a href="http://www.liucougar.net/blog/wp-content/uploads/2008/12/htmlsupport.jar">HTMLSupport jar</a> is available for download, which should work in java 1.6 (may work in previous versions as well).</p>
<h2>How to use this new HTMLSupport</h2>
<p>If you intend to use java applet (as I do in this case), then hijacking (or BootClasspath trick) does not work for IE: even if you set <code>-Xbootclasspath/p:\path\to\your\HTMLSupport.jar</code> as the runtime parameter in java control panel for java applet, it does not work. It seems IE just simply refuses to look at that configuration and uses the default bootclasspath only.</p>
<p>Short of other workarounds, I do it the brutal force way: replace the original HTMLSupport.class file in rt.jar with the patched one (you can find this file in the jar, it is the only file in there). As this is intended to be used in a virtual machine whose sole purpose is to use doh.robot to run functional tests, so it is not that bad.</p>
<p>Thanks goes to all the authors of the articles mentioned in this post.</p>
<p>One thing to note: <a href="http://www.peterbuettner.de/develop/javasnippets/clipHtml/index.html" target="_blank">the original articile</a> was written in 2003, more than five years ago, and this bug still exists in latest java stable release (which is 1.6 update 11).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/92/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Convert VirtualBox image (vdi) to VMWare (vmdk)</title>
		<link>http://www.liucougar.net/blog/archives/118</link>
		<comments>http://www.liucougar.net/blog/archives/118#comments</comments>
		<pubDate>Fri, 19 Dec 2008 07:05:48 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://liucougar.scim-im.org/blog/?p=118</guid>
		<description><![CDATA[Due to better 64bit support, we decided to use VMWare instead of VirtualBox. To prevent of installing a gentoo to a VMWare image, I decided to convert the already working virtualbox image (a vdi file) to VMWare (vmdk).

Qemu-img is the command line tool for this task, using the following line, I can get a vmdk:


qemu-img [...]]]></description>
			<content:encoded><![CDATA[Due to better 64bit support, we decided to use VMWare instead of VirtualBox. To prevent of installing a gentoo to a VMWare image, I decided to convert the already working virtualbox image (a vdi file) to VMWare (vmdk).

Qemu-img is the command line tool for this task, using the following line, I can get a vmdk:


<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">qemu-img convert <span style="color: #660033;">-O</span> vmdk gentoo32.vdi gentoo32.vmdk</pre></div></div>



However, this vmdk is not recognized by VMWare 6.5. I guess it has something to do with the fact that the original vdi file is using dynamic sizing (the file contains a 5G partition, and it only has 1.9G data, so the real size for the vdi file is about 2.1G): the converted vmdk is 1.9G, and VMWare reports that it has 2.1G total size.When booting with this image, VMWare fails to read any data from the virtual disk.

After tried another time with the above approach, which also failed, it seems I have to find another way.

Luckily, VirtualBox comes with a command line tool called vboxmanage, which can do all sorts of operations on vdi files, including converting vdi to raw disk image, so let&#8217;s try that:


<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">vboxmanage internalcommands converttoraw gentoo32.vdi gentoo32.raw</pre></div></div>



The above command will generate a 5G gentoo32.raw file. Then use qemu-img:


<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">qemu-img convert <span style="color: #660033;">-O</span> vmdk gentoo32.raw gentoo32.vmdk</pre></div></div>



To convert the raw file to vmdk. The resulting vmdk file is also 1.9G, but this time VMWare recognize it just fine (reporting its real size as 5G).

After changing the root device from <code>/dev/sda1</code> to <code>/dev/hda1</code>, this image can boot just fine in VMWare, with one exception: the network interface eth0 can not be started. More inspecting reveals that &#8220;udev renames network interface eth0 to eth1&#8243;. This is caused by the fact that one of the default gentoo udev rule (<code>/etc/udev/rules.d/75-persistent-net-generator.rules</code>) will write another rule file which saves the MAC address for each NIC, and sure enough, the MAC address for the NIC in VirtualBox is different from that of VMWare. However, this is very easy to fix, once you know where the generated udev rule is:

Open <code>/etc/udev/rules.d/70-persistent-net.rules</code> and remove all rules in this file, save and reboot, eth0 won&#8217;t be renamed to eth1 any more.]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/118/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Dojo.reload Reloaded: reload app without reloading browser</title>
		<link>http://www.liucougar.net/blog/archives/90</link>
		<comments>http://www.liucougar.net/blog/archives/90#comments</comments>
		<pubDate>Sun, 14 Dec 2008 20:56:13 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[dojo.reload]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=90</guid>
		<description><![CDATA[Dojo.reload is added to dojoc.util with two new functions, dojo.reloadPage() and dojo.reloadCss(). In addition, new features are added to the dojo.reload() function to support partial module name match and automatically removing cache of dijit templates when reloading a module containing dijit definition.]]></description>
			<content:encoded><![CDATA[<p>After introducing dojo.reload in my <a href="http://www.liucougar.net/blog/archives/89" target="_blank">previous post</a>, I talked with kriszyp in IRC, and he asked whether <code>dojo.reload</code> can actually modify already created objects from <code>dojo.declare</code>-d classes: in most web 2.0 apps, after the app is loaded, there are lots of instances of classes already created, and using <code>dojo.reload</code> to reload their definition won&#8217;t actually update any of these existing instances.</p>
<p>As I do not have an idea to actually implement that, I do come up with another &#8220;workaround&#8221; (if you like): rather than propagate changes to existing objects on the page, we can actually try to ask the app to reload itself without reloading the whole page. We don&#8217;t want to add in any special code in any frontend apps to handle this sort of &#8220;self reload&#8221; mechanism just to speed up development. Instead, a generic way should be available without any extra logic support in the application layer.</p>
<p>With the help of dojo and with one assumption, I did come up such an implementation to support that. The one assumption is that, all existing objects you care about in your applications are all dijits. If this assumption can be met, what we really need to do in order to reload an application is to:</p>
<ol>
<li>call onunload handlers (in case any are registered with dojo)</li>
<li>destroy all dijits in the page</li>
<li>reset the <code>document.body.innerHTML</code> to what it looks like when the page is first loaded (before any js actually modifys it)</li>
<li>call all onload hanlders registered with dojo (such as dojo.parser etc.)</li>
</ol>
<p>Item 3 can be achieved via a xhr call to retrieve current page from server and figure out the content within &lt;body&gt; tag. Item 4 requires a bit of extra work, because once all the onload handlers are called by dojo, they are removed. So in order to actually rerun them, we have to remember the original list of handlers.</p>
<p>Of course, as you may already figured, the method mentioned above won&#8217;t be able to run any modified onload handlers (even after they are <code>dojo.reload</code>-ed), however, it does cover most of other cases.</p>
<p>The one assumption mentioned above is not actually true in most web 2.0 applications using dojo, in such cases, any non-dijit objects have to be destroyed somehow so that they can be recreated, but that logic has to be application specific. On the other hand, in order to prevent memory leaks in browsers (espcially IE), it is always a good idea to have a destroy function for your objects to clean itself up. So if you are not worried about any thing other than dijits, then the method mentioned above should work reasonably well, while if you do want to re-create other non-dijits stuffs, you can call some application specific cleanup routines (which as I mentioned above would be good to have in any case).</p>
<p>You can find the code in <a href="http://svn.dojotoolkit.org/dojoc/util/loader.js">dojoc.util.loader</a>, the function is actually called <code>dojo.reloadPage()</code>. The normal use case for this is:</p>
<ol>
<li><code>dojo.reload</code> any modules you modified and want to test;</li>
<li><code>dojo.reloadPage</code> to actually test them without waiting for reloading all js files/reloading your browser window.</li>
</ol>
<p><strong>Note</strong>: <code>dojo.reloadPage</code> only works if it is included in the initial page load, if you <code>dojo.require dojoc.util.loader</code> after the page is loaded, dojo.reloadPage won&#8217;t work (see comment at the beginning of the file to know why)</p>
<p>dojo.reload now also resides in <code>dojoc.util.loader</code>, and compared to the <a href="http://www.liucougar.net/blog/archives/89">previous version</a>, two additional features are add:</p>
<ul>
<li>Partial module name match: now you just need to type in a partial name of the module you want to reload, if it only matches one module already loaded, that module will be reloaded. If there are multiple matches, it will list all possible modules and error out.</li>
<li>Automatically remove cache of dijit template: if a module references widget template files (using templatePath), these cached templates will be cleared automatically, so next time you create such a dijit, the new template will be loaded from your sever directly.</li>
</ul>
<p>A new function to reload css files is also included in <code>dojoc.util.loader, dojo.reloadCss</code>, which also supports partial name match. If it is given no argument, it will reload all css files in the page (with a href attribute, of course), similar to ReCSS feature in the firebug lite shipped with dojo core.</p>
<p><strong>Warning</strong>: use at your own risk.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/90/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Reverse proxy cherrypy with Apache/Nginx</title>
		<link>http://www.liucougar.net/blog/archives/91</link>
		<comments>http://www.liucougar.net/blog/archives/91#comments</comments>
		<pubDate>Sun, 07 Dec 2008 04:45:56 +0000</pubDate>
		<dc:creator>liucougar</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[dojo]]></category>

		<guid isPermaLink="false">http://www.liucougar.net/blog/?p=91</guid>
		<description><![CDATA[For the past several months, I am developing frontend against a bare cherrypy server which also serves all static files, like javascripts/images etc. Without building frontend code (so there are lots of small js files to load), it takes more than 20 seconds to reload the unbuilt frontend application I am working on (which is [...]]]></description>
			<content:encoded><![CDATA[<p>For the past several months, I am developing frontend against a <em>bare</em> cherrypy server which also serves all static files, like javascripts/images etc. Without building frontend code (so there are lots of small js files to load), it takes more than 20 seconds to reload the unbuilt frontend application I am working on (which is the main driver behind my hacking on <a href="/blog/archives/89">dojo.reload</a>).</p>

<h3>Use Apache as proxy server</h3>
<p>Today I decided to shield an apache proxy server in front of the cherrypy server to off load all static files serving duties from the latter, in the hope of speeding up reloading speed of the app.</p>

<p>The apache proxy should be setup so that it directly serves any files under /debug and /release, all other requests are dynamic and should be handled by cherrypy server. In addition, our backend app sometimes use HTTP redirects to direct client to a new page. In Apache configuration file, all this can be achieved by:</p>


<div class="wp_syntax"><div class="code"><pre class="apache apache" style="font-family:monospace;"><span style="color: #00007f;">ProxyPassMatch</span> ^/(?:debug|release)/.* !
<span style="color: #00007f;">ProxyPass</span> / http://127.0.0.1:<span style="color: #ff0000;">8000</span>/
&nbsp;
<span style="color: #00007f;">ProxyPassReverse</span> / http://127.0.0.1:<span style="color: #ff0000;">8000</span>/
&nbsp;
<span style="color: #00007f;">Alias</span> /debug /var/www/htdocs
<span style="color: #00007f;">Alias</span> /release /var/www/htdocs/release</pre></div></div>




<p>Note: the <code>/debug</code> directory is the unbuilt frontend code, while the <code>/release</code> points to the built frontend code (by default, dojo will put the built version under release directly as peer of dojo dir).</p>
<p>With the above settings, cherrypy is nicely sitting behind the Apache server without worrying about any static files, and the reloading time of the unbuilt frontend code now reduces to about 4 seconds, which is a dramatic improvement.</p>

<h3>Try nginx instead</h3>
<p><a href="http://nginx.net/">nginx</a> is normally considered to be a faster reverse proxy server than apache, so I want to give it a try. </p>
<p>In nginx configuration file, proxy_pass is used to pass the request to a backend server, while it does not use proxy_pass_reverse, instead the equivalent in nginx is proxy_redirect directive. As long as your host domain name is properly set up, the following nginx directive is equavalent to the above apache directive:</p>


<div class="wp_syntax"><div class="code"><pre class="apache apache" style="font-family:monospace;"><span style="color: #00007f;">location</span> /debug/ {
    <span style="color: #00007f;">alias</span> /var/www/htdocs;
}
<span style="color: #00007f;">location</span> /release/ {
    <span style="color: #00007f;">alias</span> /var/www/htdocs/release;
}
<span style="color: #00007f;">location</span> / {
    <span style="color: #00007f;">proxy_pass</span> http://127.0.0.1:<span style="color: #ff0000;">8000</span>;
    <span style="color: #00007f;">proxy_redirect</span> default;
}</pre></div></div>



<p>More info on proxy_redirect can be found in official <a href="http://wiki.codemongers.com/NginxHttpProxyModule#proxy_redirect">documentation</a>.</p>

<h3>Impression of Nginx compared to Apache</h3>
<p>While I don&#8217;t want to do any thorough comparsion of the two reverse proxy servers, I just tried each of them several times and monitors the net panel output in firebug. It seems, nginx delievers more consistent performance: for the same page, apache sometimes deliver it in 1 second, sometimes in 4 seconds, while nginx always delivers it in 1 second. Thus I guess I will just keep using nginx at least for now.</p>]]></content:encoded>
			<wfw:commentRss>http://www.liucougar.net/blog/archives/91/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.617 seconds -->
<!-- Cached page served by WP-Cache in 0.2124 seconds for 38.107.191.95 -->
