<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2japanesefull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>HouseTect, JavaScript Blog</title>
      <link>http://hisasann.com/housetect/</link>
      <description>Javascript、Actionscriptあたりをメインに遊んでいるプログラマーのブログです。ちょっぴりアートでオモロ〜なものを作ってます。</description>
      <language>ja</language>
      <copyright>Copyright 2010</copyright>
      <lastBuildDate>Fri, 05 Feb 2010 16:01:16 +0900</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

      
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Housetect" /><feedburner:info uri="housetect" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
         <title>TextMateのGetBundleがうまくいかないときの対処方法</title>
         <description><![CDATA[<strong>TextMate</strong>を使っていると基本的には<strong>デフォルトのBundle</strong>でことが足りるんですが、<strong>jQueryBundle</strong>入れたり、<strong>MootoolsBundle</strong>入れたりと何かしらBundleを自分でインストールする機会があります。

このときにBundleを簡単にインストールできるGetBundleを使えば、簡単にインストールできるんですが、不調なのかアップデートが必要なのかうまくいかない場合があり、
こんなときはBundleの<strong>svnリポジトリ</strong>から自分でインストールしちゃうと早いです。


<h2>
	Bundlesから選んでインストールする方法
</h2>

以下のリンクから欲しいバンドルリンクをクリックします。

<a href="http://svn.textmate.org/trunk/Bundles/" target="_blank">http://svn.textmate.org/trunk/Bundles/</a>

そのときのURLをコピーして、以下のように直接TextMateのBundlesディレクトリに<strong>チェックアウト</strong>する。

僕は自分のUserの下にTextMateのBundlesを入れているのでこんな感じ。

<textarea class="js" name="code">
cd /Users/hoge/Library/Application Support/TextMate/Bundles
svn co http://svn.textmate.org/trunk/Bundles/JavaScript%20jQuery.tmbundle/
</textarea>


システム全体で共通に使っている人は/Libraryから始めるみたい。

<textarea class="js" name="code">
cd /Library/Application Support/TextMate/Bundles
svn co http://svn.textmate.org/trunk/Bundles/JavaScript%20jQuery.tmbundle/
</textarea>


Bundlesは死ぬほど便利なので、入れまくって使いまくりましょう！！]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/liE4GZirAfw/textmategetbundle.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/02/textmategetbundle.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Mac</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Mac</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">TextMate</category>
        
         <pubDate>Fri, 05 Feb 2010 16:01:16 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/02/textmategetbundle.html</feedburner:origLink></item>
      
      <item>
         <title>Apple iPadが欲しくなる映像</title>
         <description><![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="アップル - iPad - デザイン - 革命的なマルチタッチデバイス。-1.jpg" src="http://hisasann.com/housetect/2010/02/04/%E3%82%A2%E3%83%83%E3%83%97%E3%83%AB%20-%20iPad%20-%20%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%20-%20%E9%9D%A9%E5%91%BD%E7%9A%84%E3%81%AA%E3%83%9E%E3%83%AB%E3%83%81%E3%82%BF%E3%83%83%E3%83%81%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%80%82-1.jpg" width="500" height="150" class="mt-image-none" style="" /></span>

始め、いろんな方のエントリーを読んで僕は買わないかな〜と思っていましたが、どうにもこうにも徐々に買いたい欲が湧いてきてしまった。
そもそも<strong>家でもMac</strong>、<strong>職場でもMac</strong>を使って作業をしていて、<strong>ケイタイはiPhone</strong>だしともうMac漬けなので、iPadも欲しくなってしまう。

まずは以下のApple iPadのビデオからどうぞ。
毎回思いますが、この作り手たちの声は卑怯！ｗ

<strong>Apple iPad</strong>
<object width="500" height="325"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9031647&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9031647&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="325"></embed></object>


こちらは実際にiPadに触った人たちのビデオ。
ますます欲しくなります。。

<strong>Apple iPad: iLounge.com's Complete Interface Walkthrough (720p HD)</strong>
<object width="500" height="325"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9037933&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9037933&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="325"></embed></object>

<strong>Apple iPad: Hands On</strong>
<object width="500" height="325"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9028871&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9028871&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="325"></embed></object>

<strong>iPad first impressions</strong>
<object width="500" height="325"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9048681&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9048681&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="325"></embed></object>

いやはや後すこし待ちますかっ！

<a href="http://www.apple.com/jp/ipad/" target="_blank">アップル - iPad - ウェブ、メール、写真を体験する最高の方法。</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/lHjH9V--RBY/apple_ipad.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/02/apple_ipad.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Mac</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Mac</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">iPad</category>
        
         <pubDate>Thu, 04 Feb 2010 12:51:51 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/02/apple_ipad.html</feedburner:origLink></item>
      
      <item>
         <title>JavaScript変態複雑化文法最速マスター</title>
         <description><![CDATA[<a href="http://d.hatena.ne.jp/Nagise/20100202/1265131791" target="_blank">Java変態文法最速マスター - プログラマーの脳みそ</a>をリスペクト。
<a href="http://d.hatena.ne.jp/hasegawayosuke/20100203/p1" target="_blank">JavaScript変態文法最速マスター - 葉っぱ日記</a>をリスペクト。

特に技法的なことではないんですが、functionをいろんなところで絡めて<strong>わかりにくくする</strong>ポイントをいくつか紹介。


<h2>if文にfunctionを絡めてみる</h2>

単純なifなはずなのに、条件式に即時実行のfunctionを絡めることによってよりわかりにくくできます。
さらに<strong>クロージャ</strong>をreturnして()で実行し、より複雑にする技法もとりいれてます。

<textarea class="js" name="code">
if (function(a, b) {
	return (function(a, b) {
		return a < b;
	})(1, 2);
}()) {
	console.log(1);
}
</textarea>


<h2>for文にfunctionを絡めてみる</h2>

そもそもfor文の回りにfunctionを絡めてわかりにくくし、for文の条件式にもfunctionを絡めます。
さらに<strong>クロージャ</strong>をreturnして()で実行し、より複雑にする技法もとりいれてます。

「ちなみにここでやっていることは引数の[1, 2, 3]という配列を受け取って、新しい配列にコピーしてreturnしているだけです。」

<textarea class="js" name="code">
var array = (function(arr) {
	return function() {
		var i=0,
			ret = new Array;

		for (; i < function(arr) {return arr.length;}(arr);)(function(object) {
			ret.push(object);

			(function() {++i;})();
		})(arr[i]);

		return ret;
	}
})([1, 2, 3])();
console.log(array);
</textarea>


<h2>出力結果</h2>

<blockqute>
	 [1, 2, 3]
</blockqute>


<h2>
	Objectに上記やり方を絡めてみる
</h2>

aというプロパティはただaを返せば終わりなはずなのに、わざわざfunctionでネストしてわかりにくくしています。
bというプロパティは上記<strong>if文複雑化</strong>と<strong>for文複雑化</strong>を応用して、解読が困難な状態を実現しています。

<textarea class="js" name="code">
var Hoge = {
	a: function() {
		return function() {
			return (function() {
				return "a"
			})();
		}
	},
	
	b: function() {
		if (function(a) {
			return (function(a) {
				return a == "a";
			})("a");
		}()) {
			var array = (function(arr) {
				return function() {
					var i=0,
						ret = new Array;
			
					for (; i < function(arr) {return arr.length;}(arr);)(function(object) {
						ret.push(object);
			
						(function() {++i;})();
					})(arr[i]);
			
					return ret;
				}
			})([1, 2, 3])();
			
			return array;
		}
	}
}
console.log(Hoge.b());
</textarea>


<h2>出力結果</h2>

<blockqute>
	 [1, 2, 3]
</blockqute>


<h2>
	複雑化で気を付ける点
</h2>

iをインクリメントする部分の複雑化で

<textarea class="js" name="code">
(function() {++i;})();
</textarea>

という部分がありますが、ここで

<textarea class="js" name="code">
(function(i) {++i;})(i);
</textarea>

このように引数で渡してはいけません。
外側のスコープにいるiではなく、このfunctionの関数スコープ内のiをインクリメントすることになるので無限ループになります。

これ以外にも<strong>curry化</strong>をうまく使いまくって、複雑にすることができますが、だいたい上記のことが応用できれば特に問題はありません。

<strong>※注意 function絡めは節度と必要度合いを見て実装しましょうね！</strong>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/t-4r54x3s5k/javascript_12.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/02/javascript_12.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Program</category>
        
         <pubDate>Wed, 03 Feb 2010 16:20:40 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/02/javascript_12.html</feedburner:origLink></item>
      
      <item>
         <title>エラトステネスの篩 - JavaScript版</title>
         <description><![CDATA[<a href="http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9" target="_blank">エラトステネスの篩 - Wikipedia</a>

こんな感じなのかな。。


<h2>サンプルコード</h2>

<textarea class="js" name="code">
console.log(makePrime(100));

function makePrime(maxCount) {
	var max = maxCount + 1,
		primes = new Array(max),
		ret = new Array();

	// 一旦すべて素数とする
	for (var i=1; i < max; ++i) { primes[i] = true; };

	// 素数だけ抽出
	for (var i=2; i < max; ++i) {
		if (primes[i]) {
			ret.push(i);
		
			for (var j=i; j*i <= max; ++j) {
				// 素数以外にfalseを入れる
				primes[j*i] = false;
			};
		}
	};
	
	return ret;
}
</textarea>


<h2>
	出力結果
</h2>

<blockquote>
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
</blockquote>

勉強になりました！]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/flgOjfXXiUQ/_-_javascript.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/_-_javascript.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Algorithm</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
         <pubDate>Fri, 29 Jan 2010 11:25:38 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/_-_javascript.html</feedburner:origLink></item>
      
      <item>
         <title>JavaScriptライブラリを使っていてIEで余計なリクエストが発生してしまうケース</title>
         <description><![CDATA[ここ最近フロントエンドのパフォーマンスチェックで<a href="http://www.httpwatch.com/?gclid=CKXKlrHXw58CFZAwpAodEWmxEQ" target="_blank">HttpWatch</a>を使っているんですが、これはかなり調子がいい！
特にインストールするとIEとFirefoxに追加され、Firebugのように画面の下のほうに表示されるので違和感なく使えます。

んで、このソフトを使ってサイトのパフォーマンスチェックをしていたら、IEの場合だけ

「<strong>ERROR_INTERNET_INVALID_URL</strong>」

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="httpwatch1.jpg" src="http://hisasann.com/housetect/2010/01/27/httpwatch1.jpg" width="500" height="94" class="mt-image-none" style="" /></span>

というRequestの結果が返ってきて、これってなんだろうと調べてみたら、<strong>jQuery</strong>・<strong>prototype.js</strong>・<strong>YUI</strong>を使っている場合に
IEで<strong>DomContentLoaded</strong>（DCL）判定するときに発生しているようです。

これでだいたい3〜6ミリ秒のオーバヘッドがあるよう。
ほんのちょびっとですがねｗ


<h2>jQueryの場合（ver1.2.1）</h2>

bindReady関数の中にIEだったらという分岐があり、その中で<strong>src=//:</strong>なscriptタグをdocument.writeしているのが原因。

<textarea class="js" name="code">
// If IE is used, use the excellent hack by Matthias Miller
// http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
else if ( jQuery.browser.msie ) {

	// Only works if you document.write() it
	document.write("<scr" + "ipt id=__ie_init defer=true " + 
		"src=//:><\/script>");
</textarea>

このscriptがdocument.writeされたタイミングでsrc属性のURLをGETする際に、よくわからんURLじゃ〜と言っているんでしょうね。
jQueryがこの判定方法を使っているのはおそらく<strong>1.2.1</strong>以前だと思うので、1.2.6や1.3.X、または1.4を使っている場合は問題ありません。

ちなみに1.4のDCLの判定は以下のようになっています。

<textarea class="js" name="code">
if ( document.attachEvent ) {
	// ensure firing before onload,
	// maybe late but safe also for iframes
	document.attachEvent("onreadystatechange", DOMContentLoaded);
	
	// A fallback to window.onload, that will always work
	window.attachEvent( "onload", jQuery.ready );

	// If IE and not a frame
	// continually check to see if the document is ready
	var toplevel = false;

	try {
		toplevel = window.frameElement == null;
	} catch(e) {}

	if ( document.documentElement.doScroll && toplevel ) {
		doScrollCheck();
	}
}
</textarea>

onreadystatechangeとonload、あとは今までにもあったdoScrollで判定しているようです。


<h2>prototype.jsの場合（1.6）</h2>

このprototype.jsを使っている場合が、今回の<strong>ERROR_INTERNET_INVALID_URL</strong>なRequestを送信してしまうパターンになります。
実際のコードは以下のとおり。

<textarea class="js" name="code">
document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
$("__onDOMContentLoaded").onreadystatechange = function() {
  if (this.readyState == "complete") {
    this.onreadystatechange = null;
    fireContentLoadedEvent();
  }
};
</textarea>

deferで遅延評価させて、readyStateがcompleteになったらfireしています。
この方法個人的に面白くて好きなんですが、無駄なRequestが発生してしまうのが難点ですね。

■関連記事
<a href="http://hisasann.com/housetect/2008/11/prototypejsdomloadedie.html">Prototypejsのdom:loadedを検証（IEの場合） </a>


<h2>YUIの場合</h2>

<a href="http://blog.httpwatch.com/2007/11/20/error_internet_invalid_url-httpwatch/" target="_blank">ERROR_INTERNET_INVALID_URL & HttpWatch - HttpWatch Blog</a>にはYUIでも起こると書かれていましたが、YUI2・YUI3の両方でscriptをdeferさせる方法はなかったので大丈夫でしょう。
もっと古い時代に書かれていたと思われます。

以下YUI3のDomContentLoaded判定。

<textarea class="js" name="code">
if (navigator.userAgent.match(/MSIE/)) {

    if (self !== self.top) {
        document.onreadystatechange = function() {
            if (document.readyState == 'complete') {
                document.onreadystatechange = null;
                _ready();
            }
        };
    } else {

        GLOBAL_ENV._dri = setInterval(function() {
            try {
                // throws an error if doc is not ready
                document.documentElement.doScroll('left');
                clearInterval(GLOBAL_ENV._dri);
                GLOBAL_ENV._dri = null;
                _ready();
            } catch (ex) { 
            }
        }, POLL_INTERVAL); 
    }
}
EU._simpleAdd(window, "load", EU._load);
</textarea>

ほとんどjQueryと同じです。


<h2>まとめ</h2>

今回の<strong>ERROR_INTERNET_INVALID_URL</strong>が発生してしまう可能性があるのは以下、

<ul>
	<li>jQueryは1.2.1以前を使っている場合</li>
	<li>prototype.js1.6以前を使っている場合</li>
	<li>YUI2よりも前のものを使っている場合</li>
</ul>

の3点かな。
他のライブラリも含めたらもっとあるでしょうが、とりあえず調べたのはこんだけ。
Firefoxとかだとこの現象は発生しないので、なかなか発見しずらいものではありますが、たまたま発見したのでログとして残しました。

<a href="http://www.httpwatch.com/?gclid=CKXKlrHXw58CFZAwpAodEWmxEQ" target="_blank">HttpWatch</a>以外に僕が使っているパフォーマンスチェックツールは、

<a href="https://addons.mozilla.org/ja/firefox/addon/5369" target="_blank">YSlow :: Add-ons for Firefox</a>

<a href="http://code.google.com/p/page-speed/" target="_blank">page-speed - Project Hosting on Google Code</a>

あと、

<a href="http://ajax.dynatrace.com/pages/" target="_blank">Diagnose and Prevent AJAX Performance Issues - dynaTrace AJAX Edition</a>

これIEだけなんですが、CLASS指定の個数とかID指定の個数とかわかるので、どこで遅くなっているかがわかりやすいです。

ではでは。

■関連リンク
・<a href="http://blog.httpwatch.com/2007/11/20/error_internet_invalid_url-httpwatch/" target="_blank">ERROR_INTERNET_INVALID_URL & HttpWatch - HttpWatch Blog</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/vUTNCJG7ouI/javascriptie.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/javascriptie.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">YUI</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">jQuery</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">prototypeJS</category>
        
         <pubDate>Wed, 27 Jan 2010 12:57:01 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/javascriptie.html</feedburner:origLink></item>
      
      <item>
         <title>JavaScript遅延ロード - jLazyLoader</title>
         <description><![CDATA[<a href="http://d.hatena.ne.jp/kagigotonet/20091221/1261355472" target="_blank">Gmailチームが明かすHTMLアプリケーション起動の高速化テクニック - TechTalkManiacs</a>を読んでて、こんな方法があるのか〜と関心した。
scriptタグの中をコメントアウトにしているので、初めのJavaScriptが解析されるときは無視されて、あとで<strong>eval</strong>させるという面白い方法。

<h2>
	ソースコード
</h2>

<textarea class="js" name="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html lang="en"&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
	&lt;title&gt;untitled&lt;/title&gt;
	&lt;script src="lib/jquery.js" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" charset="utf-8" id="lazy1"&gt;
	/*
	// Make sure you strip out (or replace) comment blocks in your JavaScript first.
	window.lazy = function() {
		alert("lazy!!");
	}
	*/
	&lt;/script&gt;
	&lt;script type="text/javascript" charset="utf-8" id="lazy2"&gt;
	/*
	lazy();
	*/
	&lt;/script&gt;
	&lt;script type="text/javascript" charset="utf-8"&gt;
	// jLazyLoader
	// 後からJavaScriptをロードするためのjQueryPlugin
	(function($) {
		$.jLazyLoader = function() {}
		$.jLazyLoader.load = function(selector) {
			load(selector);
		}

		function load(selector) {
		    eval(stripOutCommentBlock($(selector).html()));
		}

		// [via] http://d.hatena.ne.jp/kagigotonet/20091221/1261355472
		function stripOutCommentBlock(code) {
		    return code.replace(/^[\s\xA0]+\/\*|\*\/[\s\xA0]+$/g, "")
		}
	})(jQuery);

	// DCL
	$(function() {
		$("#lazyLoader").click(function() {
			$.jLazyLoader.load("#lazy1");
			$.jLazyLoader.load("#lazy2");
		});
	});
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;div id="lazyLoader"&gt; Lazy Load &lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</textarea>


<h2>
	ダウンロード
</h2>

<a href="http://gist.github.com/270994" target="_blank">gist: 270994 - GitHub</a>


コメントアウトにしちゃっているので可読性は低いですが、このテクニックはいつか使って速度の検証をしてみたいところ。

■関連リンク
・<a href="http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html" target="_blank">Google Code Blog: Gmail for Mobile HTML5 Series: Reducing Startup Latency</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/VWqO1YDXYaU/javascript_-_jlazyloader.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/javascript_-_jlazyloader.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Plugin</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">jQuery</category>
        
         <pubDate>Thu, 07 Jan 2010 13:35:21 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/javascript_-_jlazyloader.html</feedburner:origLink></item>
      
      <item>
         <title>eclipseの起動画面を変えて楽しむ方法</title>
         <description><![CDATA[<a href="http://d.hatena.ne.jp/torazuka/20100104/splash" target="_blank">eclipseたんスプラッシュ画像 - 虎塚</a>を見て、普段使うeclipseの起動画面で遊びたいという欲求が生まれた。

だいたい15秒から30秒くらいしか表示されないeclipseの起動画面ですが、何か自分オリジナルで面白い画像にすると幸せになるかもしれませんね。

以下オリジナルな起動画面いろいろ。


<h2>eclipse3.2</h2>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="splash3.2.jpg" src="http://hisasann.com/housetect/2010/01/05/splash3.2.jpg" width="455" height="295" class="mt-image-none" style="" /></span>


<h2>eclipse3.4 - GANYMEDE</h2>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="" src="http://hisasann.com/housetect/2010/01/05/splash3.4.jpg" width="455" height="295" class="mt-image-none" style="" /></span>


<h2>eclipse3.5 - GALILEO</h2>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="splash3.5.jpg" src="http://hisasann.com/housetect/2010/01/05/splash3.5.jpg" width="455" height="295" class="mt-image-none" style="" /></span>


そして、<a href="http://d.hatena.ne.jp/torazuka/" target="_blank">虎塚</a>さんが作った画像が以下。


<h2>eclipseたん</h2>

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="splashtan.jpg" src="http://hisasann.com/housetect/2010/01/05/splashtan.jpg" width="455" height="295" class="mt-image-none" style="" /></span>


<h2>eclipseの起動画面を変更する方法</h2>

「eclipse/plugins/org.eclipse.platform_X.X.XXX」というディレクトリの中に、<strong>splash.bmp</strong>ファイルがあるので、これを自分の好きな、或いはアレンジした画像に置き換えてあげるだけ。
これで次回の起動のときに表示されます。

かなり簡単ですね。
さぁて、画像作ろう。。。

■関連リンク
・<a href="http://d.hatena.ne.jp/torazuka/20100102/p1" target="_blank">世話焼き系IDE：eclipseたん - 虎塚</a>
・<a href="http://www.confrage.com/eclipse/others/chg_opening_bmp/chg_opening_bmp.html" target="_blank">Eclipse起動時に表示される画像を変更する</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/uvgLGORDgOI/eclipse_8.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/eclipse_8.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Eclipse</category>
        
         <pubDate>Tue, 05 Jan 2010 15:11:52 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/eclipse_8.html</feedburner:origLink></item>
      
      <item>
         <title>Googleのロゴがニュートンになってた。そしてリンゴが落ちてきた</title>
         <description><![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="tree.jpg" src="http://hisasann.com/housetect/2010/01/04/tree.jpg" width="384" height="138" class="mt-image-none" style="" /></span>

普段<a href="http://www.google.co.jp/" target="_blank">Googleトップ</a>をあんまり活用していないのでわからなかったですが、<a href="http://twitter.com/wacky_stupid" target="_blank">わっきー</a>さんに教えてもらいました。

んで、コード見てたらロゴのimgタグのonloadに<strong>リンゴを落とすJavaScript</strong>が書かれててちょっと面白かった。
imgのonload使うときって、あとから読み込んだ画像のwidth・heightを取得するときに使ったりするんですが、こうゆうトリッキーな使い方は面白いですね。

ざっくりですが、コードを抜き出してみたのが以下。


<h2>
	サンプルコード
</h2>

<textarea name="code" class="js">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html lang="en"&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
	&lt;title&gt;アイザック ニュートンの誕生日&lt;/title&gt;
	&lt;script type="text/javascript" charset="utf-8"&gt;
	var google = {};	// rein用

	window.fail = function() {
		window.lol && lol();

		setTimeout(function() {
			var h = 0,
			v = 1,
			f = document.getElementById('fall'),
			i = setInterval(function() {
				if (f) {
					var r = parseInt(f.style.right) + h,
					b = parseInt(f.style.bottom) - v;
					f.style.right = r + 'px';
					f.style.bottom = b + 'px';
					if (b &gt; -210) {
						v += 2
					} else {
						h = (v &gt; 9) ? v * 0.1: 0;
						v *= (v &gt; 9) ? -0.3: 0
					}
				}
			}, 25);

			google.rein && google.rein.push(function() {
				clearInterval(i);
				h = 0;
				v = 1
			})
		}, 2000)
	}
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;　　　　　　　　　　
	&lt;img src="tree.jpg" onload="fail();"&gt;
	&lt;img src="apple.png" style="position: relative; right:248px; bottom: 46px;" id="fall"&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea>

1個分からないのが、アニメーションの<strong>clearInterval</strong>を<strong>google.rein</strong>にpushしているんですが、
これをいったいどこで実行しているんだろう。。。

Googleトップのコードを一通りおってみたんですが、実行してそうな箇所がない。
1つだけあやしい箇所があったんですが、<strong>9zPpGAOKyhU.js</strong>の中の以下の部分。（だいぶ端折ってます）

<textarea name="code" class="js">
i = "push";
h.rein[i](function() {
	t = h.pageState;
	x()
});
</textarea>

iにはpushという文字が入っているだけで、pushされた分をループしているわけではない。。。

仕方ないので、以下のグリモンでテスト。
タイミングがもしかしたら微妙かもしれないが、リンゴが落ちたあとにclearIntervalされるはずだからonloadでもOKでしょう！


<h2>google.rein実行された？グリモン</h2>

<textarea name="code" class="js">
// ==UserScript==
// @name           google rein
// @namespace      http://hisasann.com/
// @include        http://www.google.co.jp/*
// ==/UserScript==

window.addEventListener('load',function(){
	var google = unsafeWindow.google;

	if (google)
		google.rein.push(function() {
			console.log("execute!!");
		});
}, false);
</textarea>

じっ、実行されない。。。


<h2>Firebugのprofileで調査</h2>

リンゴが落ちたあとにprofileを開始して、適当なタイミングで止めてみたのが以下の画像。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Google.jpg" src="http://hisasann.com/housetect/2010/01/04/Google.jpg" width="467" height="180" class="mt-image-none" style="" /></span>

「<strong>undefine()</strong>」の部分が、該当のアニメーション処理。
中身を見ると、

<textarea name="code" class="js">
function () {
	if (f) {
		var r = parseInt(f.style.right) + h, b = parseInt(f.style.bottom) - v;
		f.style.right = r + "px";
		f.style.bottom = b + "px";
		if (b > -210) {
			v += 2;
		} else {
			h = v > 9 ? v * 0.1 : 0;
			v *= v > 9 ? -0.3 : 0;
		}
	}
}
</textarea>

とアニメーションのクロージャが入っているので、間違いないでしょう！
<strong>profileEnd</strong>のタイミングをずらせばもっと回数の部分が増えていきます。

結局、よくわからなかったんですが、実行してないでしょ？w
いや〜分からんな〜〜〜。


<blockquote>
<p>グーグルのロゴデザインやってる人に <br> 乱歩のやつは最高だったと伝えておいてください <br><br> <span style="color: rgb(152, 115, 3);">喜ぶと思います。彼はdoodle 作るのにたくさんの資料や本を読んだり、頭があつあつになるくらい考えてますから。 <br> でも手塚治虫先生の時や藤子先生の時など漫画がたくさんおいてあるので遊んでるみたいです。 </span></p>
<cite>via: <a href="http://brow2ing.doorblog.jp/archives/1371414.html" target="_blank">グーグルで働いてるけど何か質問ある？ - ブラブラブラウジング</a></cite>
</blockquote>

[via]
<a href="http://brow2ing.doorblog.jp/archives/1371414.html" target="_blank">グーグルで働いてるけど何か質問ある？ - ブラブラブラウジング</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/qknhNrM0LDY/google.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/google.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Web</category>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Google</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
         <pubDate>Mon, 04 Jan 2010 18:01:18 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/google.html</feedburner:origLink></item>
      
      <item>
         <title>Viva 2010!! Happy New Year JavaScripters</title>
         <description><![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Viva 2010!! Happy New Year JavaScripters" src="http://hisasann.com/housetect/2010/01/01/2010.png" width="500" height="200" class="mt-image-none" style="" /></span>

明けましておめでとうございます。
昨年はいろんなJavaScripterの方の記事を参考にさせていただき、またJavaScriptが一段と発展した年でした。
今年もオモロい記事や作品がいっぱい世に出てくるんでしょうね。

さてぼちぼちJavaScriptを書き始めますかっ！！

とりあえず今制作しているものも早く完成させてリリースしていきたいとおもいます。
では本年もよろしくお願いいたします。

<strong>I Love JavaScript!!</strong>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/rKe29co6544/viva_2010_happy_new_year_javas.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2010/01/viva_2010_happy_new_year_javas.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
         <pubDate>Fri, 01 Jan 2010 01:45:01 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2010/01/viva_2010_happy_new_year_javas.html</feedburner:origLink></item>
      
      <item>
         <title>VMware fusion内のWindowsからMacにSSHでログインする方法</title>
         <description><![CDATA[Macの「<strong>システム環境設定→共有</strong>」にて以下の設定をするだけ、

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="リモートログイン-1.jpg" src="http://hisasann.com/housetect/2009/12/14/%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3-1.jpg" width="500" height="358" class="mt-image-none" style="" /></span>

IPアドレスが表示されるので、あとはWindows上からSSHクライアントでログインすればOK。

Windowsの有名どこなSSHクライアントは<a href="http://sourceforge.jp/projects/ttssh2/" target="_blank">TeraTerm</a>か<a href="http://ja.poderosa.org/" target="_blank">Poderosa</a>かな。

まぁWindowsからSSHでログインしても特に意味はないんですがねｗ]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/0uUlaMhNTJ0/vmware_fusionwindowsmacssh.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/12/vmware_fusionwindowsmacssh.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Mac</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Mac</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">SSH</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">VMware</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Windows</category>
        
         <pubDate>Mon, 14 Dec 2009 02:20:32 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/12/vmware_fusionwindowsmacssh.html</feedburner:origLink></item>
      
      <item>
         <title>XCodeでWebkitをデバッグする方法</title>
         <description><![CDATA[<strong>JavaScript</strong>のDomメソッドがどうやって動いているのか、普段あんまり意識しないですが、気になりだすと調べたくなるものです。

<strong>Webkit</strong>はSafariやGoogle Chromeに採用されているレンダリングエンジンで、高速でありアニメーションも非常になめらかです。

そんなWebkitをいつでも追えるように、デバッグ環境を作っておくと便利かも？と手順をメモしておきます。
「JavaScripterの参考になればうれしいです。」


<h2>XCodeのインストール</h2>

XCodeのインストールは、インストールディスクの中にあるOptional Installsフォルダに入っていますので、そちらからインストール可能です。
もしインストールディスクがない場合は、<a href="http://developer.apple.com/jp/mac/" target="_blank">Apple Developer Connection - Mac Dev Center</a>よりダウンロードが可能です。
ただし、AppleDeveloperConnectionへのログインが必要になります。

[via]
<a href="http://webkit.org/building/tools.html" target="_blank">The WebKit Open Source Project - Installing Developer Tools</a>


<h2>Webkitのソースコードをダウンロードする</h2>

ターミナルを起動して、まずはダウンロード先のフォルダを作成します。

<blockquote>
	cd ~
	mkdir webkit
	cd webkit
</blockquote>

次に以下を入力するとSVNからダウンロードが開始されます。

<blockquote>
	svn checkout http://svn.webkit.org/repository/webkit/trunk WebKit
</blockquote>

僕は<strong>30分以上</strong>かかったので、ランチに行くときに実行しておくとよいかもしれません。
また1度目はターミナルが途中で落ちてしまったので、あまり他の作業は行わずソースのダウンロードに専念させてあげたほうがよいかもしれません。

ソースコードのダウンロードが終わりましたら、以下を実行してください。
どうやらこれをしないとビルドがうまくいかないようです。

<blockquote>
	WebKit/WebKitTools/Scripts/update-webkit
</blockquote>

[via]
<a href="http://webkit.org/building/checkout.html" target="_blank">The WebKit Open Source Project - Getting the Code</a>


<h2>Webkitをビルドする</h2>

さっそくビルドを開始します。
以下を実行すると、ターミナルが膨大に流れ始めます。

<blockquote>
	WebKit/WebKitTools/Scripts/set-webkit-configuration --debug
	WebKit/WebKitTools/Scripts/build-webkit --debug
</blockquote>

ビルドもだいたい<strong>30分くらい</strong>かかるので、夕飯を食べにいきましょう！

成功すると以下のようにコンソールに表示されます。

<blockquote>
Touch /Users/hoge/_/code/webkit/WebKit/WebKitBuild/Debug/WebKit.framework
    cd /Users/hoge/_/code/webkit/WebKit/WebKit
    /usr/bin/touch -c /Users/hoge/_/code/webkit/WebKit/WebKitBuild/Debug/WebKit.framework
** BUILD SUCCEEDED **

===========================================================
 WebKit is now built (32m:39s). 
 To run Safari with this newly-built code, use the
 "WebKit/WebKitTools/Scripts/run-safari" script.
===========================================================
</blockquote>

[via]
<a href="http://webkit.org/building/build.html" target="_blank">The WebKit Open Source Project - Building WebKit</a>


<h2>Webkitを起動する</h2>

<blockquote>
	WebKit/WebKitTools/Scripts/run-safari --debug
</blockquote>

これで今回ビルドした内容でSafariが起動すると思います。
これでテストは完了です。


<h2>XCodeを使ってWebkitをデバッグしてみる</h2>

ではでは、いよいよWebkitをデバッグしてみます。
今回は<strong>document.getElementById</strong>をデバッグしてみようと思いますので、<strong>WebCore</strong>あたりを除いてみます。

まずはダウンロードしたWebkitのWebCoreディレクトリをFinderで表示します。
僕の場合は以下のようなパスにダウンロードしました。

<blockquote>
	/Users/hoge/_/code/webkit/WebKit/WebCore
</blockquote>

ここにXCodeのプロジェクトファイル「<strong>WebCore.xcodeproj</strong>」があると思いますので、実行してみましょう。
起動するとWebCoreプロジェクトが左のペインに表示されます。

ここのWebCoreの部分で右クリックして、「情報を見る」を選択します。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Document.cpp -- WebCore-1.jpg" src="http://hisasann.com/housetect/2009/11/30/Document.cpp%20%E2%80%94%20WebCore-1.jpg" width="481" height="276" class="mt-image-none" style="" /></span>

するとWebCoreの情報が表示されるので、

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt=""プロジェクト "WebCore""の情報.jpg" src="http://hisasann.com/housetect/2009/11/30/%E2%80%9C%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%20%E2%80%9CWebCore%E2%80%9D%E2%80%9D%E3%81%AE%E6%83%85%E5%A0%B1.jpg" width="365" height="554" class="mt-image-none" style="" /></span>

のように、「<strong>カスタムの保存場所</strong>」を指定します。
これは実際にビルドされた内容が存在するパスを指定していることになります。

次にアタッチ先となる実行可能ファイルを作成します。

「<strong>グループとファイル</strong>」ペインの真ん中あたりに「実行可能ファイル」という項目があるので、ここを右クリックし「追加」→「<strong>新規カスタム実行可能ファイル</strong>」を選択します。
以下のように<strong>Safari.app</strong>までのパスを設定します。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt=""実行可能ファイル "実行可能ファイル""の情報.jpg" src="http://hisasann.com/housetect/2009/11/30/%E2%80%9C%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%20%E2%80%9C%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E2%80%9D%E2%80%9D%E3%81%AE%E6%83%85%E5%A0%B1.jpg" width="362" height="554" class="mt-image-none" style="" /></span>

これによりデバッグ時にSafariを使う設定が完了しました。


<h2>
	Webkitにアタッチさせる
</h2>

いよいよデバッグです。
XCodeのメニューにある「実行」から「<strong>進行（デバッグ）</strong>」を選択し、デバッグモードで起動します。

この作業は少し時間がかかるので、Safariが起動するまで気長に待ちましょう！
ここでどんな作業が行われているかをコンソールから確認することができます。
以下のボタンをクリックして<strong>コンソール</strong>を立ち上げてみましょう。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Document.cpp -- WebCore-2.jpg" src="http://hisasann.com/housetect/Document.cpp%20%E2%80%94%20WebCore-2.jpg" width="500" height="119" class="mt-image-none" style="" /></span>

このように何かしらの作業が進行していると思います。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="WebCore -- デバッガコンソール.jpg" src="http://hisasann.com/housetect/2009/11/30/WebCore%20%E2%80%94%20%E3%83%87%E3%83%90%E3%83%83%E3%82%AC%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB.jpg" width="500" height="233" class="mt-image-none" style="" /></span>

Safariが起動したら、ブレークポイントを貼ってみましょう。（ここが今回の穴場です！）


<h2>document.getElementByIdにブレークポイントを貼る</h2>

左側のペインのWebCoreのdomの下に<strong>Document.cpp</strong>というファイルがあるので、これをクリック。
すると右側のペインにソースコードが表示されるので、「Cmd + F」でgetElementByIdを検索してみます。
（シンボルを選択するプルダウンからもメソッドを表示することができますが、今回は検索機能を使ってみます。）

すると以下のようなコードにたどり着くと思います。

<textarea class="java" name="code">
Element* Document::getElementById(const AtomicString& elementId) const
{
    if (elementId.isEmpty())
        return 0;

    Element* element = m_elementsById.get(elementId.impl());
    if (element)
        return element;

    if (m_duplicateIds.contains(elementId.impl())) {
        // We know there's at least one node with this id, but we don't know what the first one is.
        for (Node *n = traverseNextNode(); n != 0; n = n->traverseNextNode()) {
            if (n->isElementNode()) {
                element = static_cast<Element*>(n);
                if (element->hasID() && element->getAttribute(idAttr) == elementId) {
                    m_duplicateIds.remove(elementId.impl());
                    m_elementsById.set(elementId.impl(), element);
                    return element;
                }
            }
        }
        ASSERT_NOT_REACHED();
    }
    return 0;
}
</textarea>

そうです。これがdocument.getElementByIdの実体です。
普段使いに使いまくってるメソッドを見れるのはうれしいですね〜。

では簡単なHTMLファイルを作ってデバッグしてみましょう！

<textarea class="js" name="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
	&lt;title&gt;untitled&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id="hogehoge"&gt;hoge&lt;/div&gt;
	&lt;script type="text/javascript" charset="utf-8"&gt;
		alert(document.getElementById("hogehoge").innerText);
	&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</textarea>

デバッグを貼るポイントはとりあえず、以下のifのところにしてみましょう。

<textarea class="js" name="code">
if (elementId.isEmpty())	// ここです
    return 0;
</textarea>

すると以下のようにブルーのしおりのようなものが表示されるので、これが<strong>ブレークポイント</strong>になります。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Document.cpp -- WebCore-3.jpg" src="http://hisasann.com/housetect/2009/11/30/Document.cpp%20%E2%80%94%20WebCore-3.jpg" width="390" height="195" class="mt-image-none" style="" /></span>

これで先ほどのHTMLファイルをSafariで開いてみますが、まだアラートは表示されません。
document.getElementByIdにブレークポイントを貼っているので、アラートが表示される前にデバッガがWebkitの実行を待ち状態にしています。


<h2>
	デバッガを使ってみる
</h2>

ここで便利なのがデバッガです。
デバッガは以下のようにボタンになっているのでクリックすれば起動されます

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Document.cpp -- WebCore-4.jpg" src="http://hisasann.com/housetect/2009/11/30/Document.cpp%20%E2%80%94%20WebCore-4.jpg" width="403" height="174" class="mt-image-none" style="" /></span>

HTMLファイルを開くとブレークポイントのところでストップします。
あとはステップオーバーしたり、ステップインしたりして遊んでみてください。

変数の監視でelementIdを見ることは出来るのですが、UChar *を16進で表示しているので本当にgetElementByIdで渡した文字列が入っているのかが確認できません。
バイナリから判断することはできるのですが、デバッガウィンドウに直接文字列が表示してほしいところです。
値を他の形式で表示してもうまくいかないので、ここは後で調査します。


<h2>Windowsでのデバッグについて</h2>

今回はMacのXCodeを使ってWebkitをデバッグしてみましたが、もちろんWindowsのほうでもデバッグは可能です。
手順は以下のリンクに詳細が載っていますが、Mac版とくらべてややこしそうです。

VisualStudioをインストールして、さらにパッチなども当てなくてはいけないので、サクッと試したい場合はMac版のほうが簡単そうです。

<a href="http://d.hatena.ne.jp/gyuque/20070927" target="_blank">WebKitビルドガイド（ドザー用） - 最速チュパカブラ研究会</a>


<h2>
	まとめ
</h2>

document.getElementByIdを追ってみましたが、何度か実行しているとあることに気がついてきます。
elementIdより該当のidを持つエレメントを探しにいくんですが、<strong>m_elementsById.get()</strong>を実行してすでにモジュール変数にエレメントがある場合は検索処理をスキップします。
つまりサイトを開いて、Cmd + Rを押すとすでにm_elementsByIdにエレメントが入っているので、高速に動くみたいですね。
こうゆう情報は実際に追ってみないとなかなか分からないものです。

ソースコードも膨大ですが、XCodeでのビルドも結構時間がかかりますが、今後面白い内容が発見できたらブログにアップしていこうと思います。

■参考リンク
・<a href="http://d.hatena.ne.jp/paella/20090714/1247568920" target="_blank">[Tips] Xcodeでプログラム実行と同時にコンソールウィンドウを表示させる方法 - Ni chicha, ni limona -平均から抜けられない僕-</a>
・<a href="http://lightchaos.blog10.fc2.com/blog-category-10.html" target="_blank">Mac OSX Build and Run! Xcodeの入手方法</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/iX-2Q8haFFk/xcodewebkit.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/11/xcodewebkit.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Web</category>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Chrome</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Mac</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Safari</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Webkit</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">XCode</category>
        
         <pubDate>Mon, 30 Nov 2009 19:17:40 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/11/xcodewebkit.html</feedburner:origLink></item>
      
      <item>
         <title>TumblrからランダムにURLを取得してTwitterにPostするbotを作ってみた</title>
         <description><![CDATA[自分の<strong>Tumblr</strong>からランダムに1時間毎に<strong>Twitter</strong>にPostするbotを作ったので、そのやりかたのメモメモ。


<h2>Tumblrから取得してTwitterにPostする手順</h2>

Tumblrから取得するのは普通にAPIを見ながらやってみた。
<a href="http://www.tumblr.com/api/" target="_blank">API | Tumblr</a>

ここで困ったのが、http://hoge.tumblr.com/randomという感じでURLの最後にrandomというのを付けるとランダム記事に飛べるという機能があるんですが、
これ相当のAPIがなかったこと。

なので1度、TumblrAPIからtotal数を取得して、その値からランダム値を生成してランダムな記事のURLを再度TumblrAPIから取得しています。

Tumblrから1つの記事を取得するには以下のようなURLを指定すればよい。
typeで<strong>photo</strong>を指定して写真を取りにいってます。

<blockquote>
	http://hoge.tumblr.com/api/read?start=0&num=1&type=photo
</blockquote>

最近さくらインターネットを借りたので、せっかくなのでRubyで書いてみた。

ちなみにTwitterにPostするときは、定番そうな<strong>twitter (0.7.0)</strong>を使っています。


<h2>RandomTumble - ソースコード</h2>

<textarea class="ruby" name="code">
require "rubygems"
require "net/http"
require "rexml/document"
require 'twitter'

class RandomTumble
  attr_accessor :id, :tumblelog, :posts, :url

  def initialize(id)
    @@uri = id + '.tumblr.com'
    @id = id
  end

  def random_post_twitter(id, pass)
    random()
    post_twitter(id, pass)
  end

  def random
    Net::HTTP.start(@@uri, 80) {|http|
      request_tumblr(http, 0, 1, "photo")

      rand_page = rand(@posts.attributes["total"].to_i - 1)

      request_tumblr(http, rand_page, 1, "photo")
      @posts.each {|post|
        @url = post.attributes["url"]
      }
    }
  end

  def request_tumblr(http, start, num, type)
    req = getReq()
    req.set_form_data(getData(start, num, type))
    res = http.request(req)
    doc = nil
    if res.kind_of?(Net::HTTPSuccess)
      doc = REXML::Document.new(res.body)
    else
      raise ResponseError.new(res)
    end

    if doc
      @tumblelog = REXML::XPath.first(doc, "//tumblelog")
      @posts = REXML::XPath.first(doc, "//posts")
    end
  end

  def post_twitter(id, pass)
    httpauth = Twitter::HTTPAuth.new(id, pass)
    twit = Twitter::Base.new(httpauth)
    twit.update(makeMessage())
  end

  def getReq
    return Net::HTTP::Post.new("/api/read")
  end

  def getData(start, num, type)
    return {
      "start" => start,
      "num" => num,
      "type" => type
    }
  end

  def makeMessage
    return @url
  end
end
</textarea>

■ダウンロード
<a href="http://gist.github.com/245238" target="_blank">gist: 245238 - GitHub</a>

<h2>
	使い方
</h2>

RandomTumbleをnewするときにTumblrのidを渡して、random_post_twitterにTwitterのidとpasswordを渡します。

<textarea class="ruby" name="code">
RandomTumble.new("hoge").random_post_twitter("id", "password")
</textarea>

これでTumblrからランダムに1件抽出して、TwitterにPostされます。
ねっ！、簡単でしょ？


<h2>cronを設定する</h2>

さくらのコントロールパネルで、以下を設定する。

・実行コマンド

試行錯誤の結果このようになりました。

<blockquote>
cd /home/User/code/ruby/; /usr/User/bin/ruby /home/User/code/ruby/twitter_bot.rb
</blockquote>

[via]
<a href="http://blog.orval-net.com/archives/2008/01/_cron.html" target="_blank">Orvalで行こう！: さくらインターネット cron設定でRubyを動かす</a>

・環境変数の設定

RUBYLIB - /home/User/lib
GEM_HOME - /home/User/lib/ruby/gem

これしとかないとrubygemsがありませんとエラーになってしまうので、忘れないように。

[via]
<a href="http://d.hatena.ne.jp/con_mame/20080704" target="_blank">さくらサーバのCronでRubyを動かす時のメモ - まめ畑</a>

・日時の設定

月 - *
日 - *
時 - */1
分 - 0

曜日すべてにチェック

初めのうちはテストとして5分ごとにして、動作確認しました。


<h2>
	作ったもの
</h2>

<a href="http://twitter.com/tback_bot" target="_blank">tbacker (tback_bot) on Twitter</a>

現時点で6500枚からランダムに選んでいますw
好きな人は好きになるはずっ！

■参考リンク
・<a href="http://www.ruby-lang.org/ja/man/html/Net_HTTP.html" target="_blank">Net::HTTP - Rubyリファレンスマニュアル</a>
・<a href="http://twitter.rubyforge.org/twitter/" target="_blank">twitter 0.7.0</a>]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/RmcI8mKMx_Q/tumblrurltwitterpostbot.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/11/tumblrurltwitterpostbot.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Web</category>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">Ruby</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Tumblr</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Twitter</category>
        
         <pubDate>Mon, 30 Nov 2009 09:06:18 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/11/tumblrurltwitterpostbot.html</feedburner:origLink></item>
      
      <item>
         <title>jQuery Plugin - 僕のmakeClass</title>
         <description><![CDATA[結構前にJohn Resig氏が<a href="http://ejohn.org/blog/simple-class-instantiation/#postcomment" target="_blank">John Resig - Simple "Class" Instantiation</a>で<strong>newしてもしなくてもよいclass</strong>を作る<strong>makeClass</strong>というメソッドをブログに載せていました。

ここ最近はprototype.jsを使わずにJavaScriptをコーディングする機会が増えてきたので、<strong>Class.create()</strong>の変わりになるこのmakeClassを重宝しています。

んで、これを自分が使いやすいように、改良して使っているのでそれを紹介してみます。


<h2>makeClass - before</h2>

<textarea class="js" name="code">
function makeClass(){
	return function(args){
		if ( this instanceof arguments.callee ) {
			if ( typeof this.init == "function" )
				this.init.apply( this, args.callee ? args : arguments );
		} else
			return new arguments.callee( arguments );
	};
}
</textarea>

なかなかトリッキーで面白いコードですね〜。
このnewしてもしなくても良いという部分がオモロい！

newせずに関数が呼び出された場合は、elseのほうに入って自分自身をnewしてからもう一度同じ関数を呼んでいます。


<h2>makeClass - after</h2>

では自分用にカスタマイズしたほうです。

<textarea class="js" name="code">
(function($) {
	$.makeClass = function(prop){
		var func = function(args){
			if ( this instanceof arguments.callee ) {
				if ( typeof this.init == "function" )
					this.init.apply( this, args ? (args.callee ? args : arguments) : arguments );
			} else
				return new arguments.callee( arguments );
		}
		func.prototype = prop || {};
		return func;
	};
})(jQuery);
</textarea>

対して変わってはいないんですが、

まずprototype.js - 1.6のClass.create()では、引数にprototypeに追加してほしいObjectを渡すことができましたので、
それと同じようにmakeClassにもpropという引数を追加。
それをreturnするfunctionのprototypeに詰めとく。

次にmakeClassを<strong>jQueryのPlugin</strong>にしてしまう。
これでグローバル名前空間を汚さずに済みます。

あとbeforeのほうの以下の部分ですが、この書き方だとクラスをnewする際に引数を渡さないとargsがundefinedになってしまい、そのcalleeを見に行くのでエラーになってしまいます。

<textarea class="js" name="code">
this.init.apply( this, args.callee ? args : arguments );
</textarea>

なので、ちょっと回りくどいですが、三項演算子でargsがあるかどうかで処理を分岐しています。

<textarea class="js" name="code">
this.init.apply( this, args ? (args.callee ? args : arguments) : arguments );
</textarea>


<h2>
	使ってみる
</h2>

initメソッドはあればインスタンス生成時に実行され、なければ実行されません。

<textarea class="js" name="code">
var Hoge  = $.makeClass({
	init: function() {
	},
	message: "hoge",
	showMessage: function() {
		console.log(this.message);
	}
});

var hoge = Hoge();		// or new Hoge()
hoge.showMessage();
</textarea>

結構すっきりした感じで書けたと思います。
jQuery Pluginの制作で、要素ごとに何か情報を持たせようとした場合は、prototypeを使うので、そういった場面でmakeClassが役立ちます。]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/q7FLyjRJ6UU/jquery_plugin_-_makeclass.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/11/jquery_plugin_-_makeclass.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">jQuery</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">prototypeJS</category>
        
         <pubDate>Thu, 26 Nov 2009 17:38:03 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/11/jquery_plugin_-_makeclass.html</feedburner:origLink></item>
      
      <item>
         <title>IE6でセキュリティ情報ダイアログがでるパターン</title>
         <description><![CDATA[IE6の対応はまだまだ必要な時代ではありますが、<strong>https</strong>でアクセスする際に<strong>セキュリティ情報</strong>のダイアログが表示されてしまうパターンを忘れないようにメモしときます。
他にもありましたら、コメント欄で教えていただけたらと思います。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Security Information.jpg" src="http://hisasann.com/housetect/2009/11/25/Security%20Information.jpg" width="332" height="137" class="mt-image-none" style="" /></span>
（※画像はIETesterでのセキュリティ情報ダイアログ）


<h2>iframeにsrc属性がない場合</h2>

SSLで開いている画面に<strong>iframe</strong>タグがあり、その<strong>src属性</strong>に何も指定されていない場合にIEがセキュリティ保護されているか判断できないために、発生するようです。

<textarea class="html" name="code">
&lt;iframe id="testframe"&gt;
</textarea>

これは例えば、lightbox風のJavaScriptを作っているときに、IEでselectboxが前面に来てしまう問題を回避するために、iframeをoverlayレイヤーとして使用するときに発生します。
jQueryライブラリのthickboxでこの問題が発生していました。

■解決策

<textarea class="html" name="code">
&lt;iframe id="testframe" src="/dummy.html"&gt;
</textarea>

のように<strong>ダミーなhtml</strong>を表示するようにすれば回避できます。

[via]
<a href="http://support.microsoft.com/kb/261188/ja" target="_blank">[PRB] FRAME/IFRAME を含むページを SSL により参照するとセキュリティ警告メッセージが発生する</a>


<h2>httpsな画面でhttpなリクエスト</h2>

SSLで開いている画面に<strong>httpでアクセス</strong>している箇所が存在するとセキュリティダイアログが表示されてしまう。
たとえば下記のように画像ファイルをhttp経由で取得場合とかだ。

<textarea class="html" name="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html lang="en"&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
	&lt;title&gt;untitled&lt;/title&gt;
	&lt;meta name="generator" content="TextMate http://macromates.com/"&gt;
&lt;/head&gt;

&lt;img src="http://www.google.co.jp/intl/ja_jp/images/logo.gif"&gt;

&lt;/html&gt;
</textarea>

<blockquote>
<p>iframeにsrc属性がないと、URLがabout:blankとなり、
<br>about:とhttps:でのスキーマ違いにより、
<br>セキュリティ警告が出るようだ。
</p>
<cite>via: <a href="http://blogs.wankuma.com/kacchan6/archive/2007/04/22/72425.aspx" target="_blank">SSLなページを開くときにセキュリティ情報というダイアログが出る</a></cite>
</blockquote>

■解決策

外部サーバーに直接取りにいかずに、手元のサーバーにアップして

<textarea class="html" name="code">
	&lt;img src="/images/logo.gif"&gt;
</textarea>

としてアクセスすればhttpsで取得しにいくのでダイアログは表示されなくなる。

■問題点

このようにこちら側でhttpからhttpsのリクエストに変更できる場合は問題がないが、
外部サービスのscriptを読み込んでいる場合はちょっと難しい。

プロキシを作成して、サーバーサイドでscriptを読み込み、<strong>str.replaceAll("http", "https")</strong>のように書き換える必要がある。
外部サービスにhttps用のscirptが用意されているのが一番良いが、そうでない場合はダイアログが表示されてしまいますね。


<h2>
	jQuery.animateのcompleteでremoveするとダイアログが出る場合がある
</h2>

たとえば以下のサンプルのように、divタグにcssで<strong>background画像</strong>を指定して、クリック時にanimateしcompleteで要素を削除するなどの場合で
SSL環境だとダイアログが出てしまう場合がある。
というか今の時点だと100%出る。（IE7では出ない）

<textarea class="js" name="code">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html lang="en"&gt;
&lt;head&gt;
	&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&gt;
	&lt;title&gt;untitled&lt;/title&gt;
	&lt;meta name="generator" content="TextMate http://macromates.com/"&gt;
	&lt;script src="./jquery.js" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;
	&lt;script type="text/javascript" charset="utf-8"&gt;
		$(function() {
			$("#hoge")
				.css({
					// どっちでも再現する
					// background: "transparent url(./profile.gif) top left"
					backgroundImage: "url(./profile.gif)"
				})
				.click(function() {
				$(this)
					.animate({
							opacity: 0
						}, {
						duration: 600,
						easing: "swing",
						complete: function(){
							// どっちでも再現する
							// $(this).remove();
							this.parentNode.removeChild( this );
						}
					}
				);
			});
		});
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;div id="hoge"&gt;hoge&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</textarea>

background、backgroundImageのどちらでも再現するので、画像を指定した場合にcomplete直後だと何かブラウザ側の処理が残っていて、
その前にremoveしちゃうから出るのかな？

■解決策

とりあえずsetTimeoutで処理を後回しにすればダイアログは表示されなくなる。
かなり特殊なパターンなので、トレースが難しいがlightBox風のものを作っている人なら遭遇したことがあるかもしれない。

<textarea class="js" name="code">
var _this = this;
setTimeout(function(){
	$(_this).remove();
}, 0);
</textarea>

■追記

IE6のセキュリティダイアログは非表示にすることもできるよう。

<a href="http://www.infopathdev.com/blogs/greg-jp/archive/2007/05/15/Internet-Explorer-_6E30AF30ED30B930C930E130A430F330_-_BB30AD30E530EA30C630A3306E30C030A430A230ED30B030_-_DC30C330AF30B9304C3068883A7955308C306A304430883046306B3059308B30_.aspx" target="_blank">Internet Explorer のクロスドメイン セキュリティのダイアログ ボックスが表示されないようにする - Greg Collins</a>

ここを参考にIE6側に設定をすればいいみたいですね。]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/RZk3rVslyD4/ie6_1.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/11/ie6_1.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Web</category>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">IE6</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
         <pubDate>Wed, 25 Nov 2009 13:19:06 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/11/ie6_1.html</feedburner:origLink></item>
      
      <item>
         <title>JavaScript - 右クリックを判定する（Operaもいけた）</title>
         <description><![CDATA[以下ようにOperaとIEで判断が必要ですが、jQueryを使っているならOperaだけの判断でOK。

<textarea class="js" name="code">
if (document.addEventListener) {
	if (window.opera) {
		// Opera
		document.addEventListener('mousedown', function(e) {
			// Operaの場合はcontextmenuをサポートしていないので、buttonから判定する
			if(e.button == 2) {
				alert("right click");
			}
			e.preventDefault();
		}, false);
	} else {
		// Firefox, Safari
		document.addEventListener("contextmenu", function(e) {
			alert("right click");
			e.preventDefault();
		}, false);
	}
} else {
	// IE
	document.attachEvent("oncontextmenu", function(e) {
		alert("right click");
		e.returnValue = false;
	});
}
</textarea>

ただし、<a href="http://d.hatena.ne.jp/higeorange/20090317/1237273929" target="_blank">Opera の右クリックイベント検出 - Higé au lait</a>にも記載されていますが、<strong>Opera側の設定</strong>をしてやる必要があります。
つまりデフォルトの状態だと右クリックをハンドルすることはできない。

<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="JavaScript オプション" src="http://hisasann.com/housetect/2009/11/19/JavaScript%20%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3.jpg" width="424" height="363" class="mt-image-none" style="" /></span>

この画像のように、チェックを入れてあげると右クリック時の<strong>mousedown</strong>をハンドルできるようになる。

また

<blockquote>
<p>まだ問題がある。コンテキストメニューを表示させないで処理を実行することができない。 preventDefault() でも駄目。</p>
<cite>via: <a href="http://d.hatena.ne.jp/higeorange/20090317/1237273929" target="_blank">Opera の右クリックイベント検出 - Higé au lait</a></cite>
</blockquote>

というふうに書かれていたんですが、Opera10では<strong>preventDefault</strong>を実行しなくともコンテキストメニューが表示されなかった。
バージョン10からそうなったのかな？]]></description>
         <link>http://feedproxy.google.com/~r/Housetect/~3/drmTzuZ45mw/javascript_-_opera.html</link>
         <guid isPermaLink="false">http://hisasann.com/housetect/2009/11/javascript_-_opera.html</guid>
        
          <category domain="http://www.sixapart.com/ns/types#category">Web</category>
        
          <category domain="http://www.sixapart.com/ns/types#category">技術</category>
        
        
          <category domain="http://www.sixapart.com/ns/types#tag">JavaScript</category>
        
          <category domain="http://www.sixapart.com/ns/types#tag">Opera</category>
        
         <pubDate>Thu, 19 Nov 2009 17:36:17 +0900</pubDate>
      <feedburner:origLink>http://hisasann.com/housetect/2009/11/javascript_-_opera.html</feedburner:origLink></item>
      
   </channel>
</rss>
