はてなマップの不具合の原因はprototype-1.3.1.js

idea:6490で報告した通り、現在はてなマップの不具合が発生していて、まともにはてなマップ使えなくなっています。まだ回復されていません。

そこで何かお手伝いできないか?と思いました。はてなマップの不具合をシンプルなコードで再現することができれば、問題解決に寄与できると直感的に感じました。

それでちょっと気になっていたことがあります。
このエントリにおけるid:Kscさんのコメントでprototype.jsが原因かもしれないとの指摘がありました。

私の確認したところ、うちも含めて他のマップは全て正常なので、はてなマップ固有の現象みたいですね。
prototype.js が絡んじゃったりしてるような気がしますが、そうなると、私も厄介な予感がします。

悪い予感がしたので、試しに私の環境で簡単なコードを書いてみました。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<script src="http://maps.google.com/maps?file=api&v=1&key=***" type="text/javascript"></script>
	<script src="prototype-1.3.1.js" type="text/javascript"></script>
</head>
<body>
	<div id="map" style="width: 500px; height: 400px"></div>
	
	<script type="text/javascript">
	//<![CDATA[
	var map = new GMap(document.getElementById("map"));
	var p = new GPoint(-122.1419, 37.4419);
	map.addControl(new GSmallMapControl());
	map.centerAndZoom(p, 4);
	var marker = new GMarker(p);
    
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml('hello');
	});
	
	map.addOverlay(marker);
	//]]>
	</script>
</body>
</html>

予感は的中していました。このコードの上でprototype-1.3.1.jsをロードしています。これが原因でした。prototype-1.3.1.jsをロードしないようにすると、正常に動作します。

実際にこのコードを実行してみると、はてなマップと全く同じバグを再現できていることがわかります。ここをご覧下さい。

さて、バグの再現ができたのは良いですが、prototype-1.3.1.jsが原因となると、かなり厄介ですね。prototype-1.3.1.jsをhack(パッチ作成)する必要があります。はてなスタッフさんの腕の見せ所ですね。

それにしても、何でprototype-1.3.1.jsが原因なんでしょう?全く検討がつきません。

追記 10/7 9:45

Google Maps APIメーリングリストはてなスタッフの方が投稿されたスレッドにも一応、レスを書いておきました。障害復旧のお役に立てれば幸いです。

Hello, I'm a Hatena user, id:ysano2005.

This problem is because of using prototype-1.3.1.js in your Hatena::Map
service.

I wrote a blog entry about this problem. How to solve the problem is
not described in this entry, however. Please see the entry (japanese).
http://d.hatena.ne.jp/ysano2005/20051007/1128643649

追記2 10/7 14:50

ちょっとこちらでも調査中。どうやらprototype-1.3.1.jsの35行目にある以下のコードが原因であることが判明。二分法的にエラー箇所を特定しました。JavaScriptの勉強不足で確信はできませんが、このコードは恐らくJavaScriptで継承を実現するためのコードです。prototype.jsの根幹となる所でエラーになってるので、かなり深刻な感じがしています。大丈夫でしょうか、はてなさん。

Object.prototype.extend = function(object) {
  return Object.extend.apply(this, [this, object]);
}

もしかすると、以下のエントリが問題解決の糸口になるかも?

追記3 10/7 22:30

id:secondlifeさんが「はてなマップの prototype.js による Object.prototype 汚染の弊害」なるエントリを書かれました。やっぱりObject.prototype汚染問題でした。1.4系のprototype.jsでは、この汚染問題は解消されているようです。

実は、今開発しているシステムも、はてなマップと同様にprototype-1.3.1.js + Google Maps APIなシステム構成なのです。それで、はてなマップと全く同様の現象が出て、困り果てていました。解決方法がわかったので、また明日バグ修正してみよう。id:secondlifeさん、情報ありがとうございました。本当に助かりました。