var AjaxViewer = function( id ) {
  this.initialize( id );
};
 
AjaxViewer.prototype = {
  /* デフォルトでは ajax_viewer_id を書き換える */
  id : 'ajax_viewer_id',
  
  initialize : function( id ) {
    /* 引数で id が与えられたら this.id を変更 */
    if ( id ) this.id = id;
    
    /* XMLHttpRequest を生成 */
    if ( window.XMLHttpRequest ) {
      // Firefox, Safari, IE7
      this.request = new XMLHttpRequest( );
    } else {
      try {
        // IE 6.0 以上
        this.request = new ActiveXObject( 'Msxml2.XMLHTTP' );
      } catch( e ) {
        try {
          // IE 5.5 以下
          this.request = new ActiveXObject( 'Microsoft.XMLHTTP' ); 
        } catch( e ) {
          this.request = null;
        }
      }
    }
  },
 
  escape_for_safari : function( low_text ) {
    /**
     * Safari の文字化対応
     * （参考：http://kawa.at.webry.info/200511/article_9.html）
     */
    if ( navigator.appVersion.indexOf( 'KHTML' )> -1 ) {
      var escaped_text = escape( low_text );
      if ( escaped_text.indexOf( '%u' ) <0 &&
           escaped_text.indexOf( '%'  )> -1 ) {
        return decodeURIComponent( escaped_text );
      }
    }
    return low_text;
  },
 
  callback : function( self ) {
    var area = document.getElementById( self.id );
    area.innerHTML = self.escape_for_safari( self.request.responseText );
  },
 
  load : function( url ) {
    if ( !this.request ) return;
    this.request.open( 'GET', url, true );
    /**
     * 内部で定義された function() では this にアクセスできないので
     * this の代わりに self という変数を用意する
     * （参考：http://d.hatena.ne.jp/cloned/20070301）
     */
    var self = this;
    this.request.onreadystatechange = function( ) {
      if ( self.request.readyState == 4 &&
           self.request.status     == 200 ) {
        self.callback( self );
      }
    };
    this.request.send( '' );
  }
 
}; 
