Closure Library を使ったルート検索

Closure Library には、ユーザー インターフェース ウィジェットから通信ユーティリティまで、さまざまなツールが含まれています。ライブラリの各部には、コードを整理して使いやすくするために一連の規則が共有されています。

この記事では、Closure Library コードベースの主な規則について簡単に説明します。この記事をお読みになった後は、こうした慣例を十分に理解し、「スタートガイド」演習を行い、ライブラリを詳しく調べることができます。

クロージャ ライブラリの名前空間

すべての Closure ライブラリ関数とプロパティの名前は、ドット区切りパスで始まります。これにより、Closure ライブラリ以外のコードで定義された名前と誤って重複することがなくなります。このパスは名前空間と呼ばれます。

たとえば、次の Closure ライブラリのコードでは、goog.math 名前空間内で clamp() 関数を定義しています。

goog.math.clamp = function(value, min, max) {
  return Math.min(Math.max(value, min), max);
};

この関数は次のように呼び出すことができます。

  var clampedValue = goog.math.clamp(2, 3, 4);

goog は Closure Library 名前空間のルートです。Closure Library の名前はすべて goog で始まります。

依存関係の管理: goog.require()goog.provide()

Closure Library の JavaScript ファイルはすべて、次のようなコード セクションから始まります。

goog.provide('goog.math');

goog.require('goog.array');
goog.require('goog.math.Box');
goog.require('goog.math.Coordinate');
goog.require('goog.math.Range');
goog.require('goog.math.Rect');
goog.require('goog.math.Size');

クロージャ ライブラリ ファイルの先頭の goog.provide() ステートメントは、そのファイルによって提供されるパブリックの名前空間とクラスを宣言します。goog.require() ステートメントは、このファイルに必要な Closure ライブラリの他の部分を示します。goog.provide()goog.require() はどちらも、Closure Library ファイル closure/goog/base.js で定義されている関数です。

goog.provide()goog.require() はともに、Closure Library の依存関係管理システムを提供します。このシステムでは、必要な Closure ライブラリの部分を簡単に組み立てることができます。

独自のコードで goog.require() 関数を使用して、必要な Closure ライブラリの部分を読み込みます。goog.require() を使用して Closure Library パッケージを読み込む方法については、Closure Library のスタートガイドをご覧ください。

継承

クロージャ ライブラリは、関数 goog.inherits() を使用して継承メカニズムを JavaScript に追加します。Closure ライブラリは、この関数を使用してコードベースをクラスとサブクラスに整理します。

たとえば、次のコードは、Button クラスを継承する MenuButton Closure Library クラスのコンストラクタを定義しています。

goog.ui.MenuButton = function(content, opt_menu, opt_renderer, opt_domHelper) {
  goog.ui.Button.call(this, content, opt_renderer ||
      goog.ui.MenuButtonRenderer.getInstance(), opt_domHelper);

  // Menu buttons support the OPENED state.
  this.setSupportedState(goog.ui.Component.State.OPENED, true);

  if (opt_menu) {
    this.setMenu(opt_menu);
  }
  this.timer_ = new goog.Timer(500);  // 0.5 sec
};
goog.inherits(goog.ui.MenuButton, goog.ui.Button);

上記のコードの最後のステートメントである goog.inherits(goog.ui.MenuButton, goog.ui.Button) は、Button のサブクラスとして MenuButton を確立します(closure/goog/base.jsgoog.inherits() の実装を確認できます)。goog.inherits() に対するこの呼び出しにより、次のように、メソッド goog.ui.MenuButton.prototype.getValue() がない場合でも、MenuButton インスタンスで getValue() メソッドを呼び出すことができます。

  var btn = new goog.ui.MenuButton('hi');
  var value = btn.getValue();

MenuButtonButton から getValue() メソッドを継承します。

次に示すように、MenuButton コンストラクタの最初の行で Button コンストラクタが呼び出されます。

goog.ui.MenuButton = function(content, opt_menu, opt_renderer, opt_domHelper) {
  goog.ui.Button.call(this, content, opt_renderer ||
      goog.ui.MenuButtonRenderer.getInstance(), opt_domHelper);
  ...
};
goog.inherits(goog.ui.MenuButton, goog.ui.Button);

継承を正しく確立するには、このようなスーパークラス コンストラクタを呼び出す必要があります。goog.inherits() を使用して独自のコードで継承を作成することもできますが、必ず call() でスーパークラス コンストラクタを呼び出してください。

各クラスの API ドキュメントには、そのクラスの継承階層と、そのクラスがスーパークラスから継承したすべてのメソッドが記載されています。

クロージング ライブラリのイベント

最新のブラウザでは、ユーザー アクションに応じてイベントを使用して JavaScript 関数がトリガーされます。残念ながら、ブラウザごとにイベント システムが異なります。

クロージャ ライブラリは独自のイベント フレームワークを定義しており、すべてのブラウザで同じように動作します。さらに、このフレームワークでは、プログラマーが独自のイベントタイプを定義してディスパッチできます。Closure Library は、コードベース全体でイベント フレームワークを使用しているため、DOM 要素をリッスンするのと同じように Closure Library のオブジェクト イベントをリッスンできます。

たとえば、ライブラリの折りたたみ可能な要素ウィジェット(goog.ui.Zippy)のコードでは、イベント フレームワークを使用して、ユーザーのクリックに対するリスナーをアタッチしています。

goog.events.listen(this.elHeader_, goog.events.EventType.CLICK,
    this.onHeaderClick_, false, this);

このコードは、イベント リスナーを DOM 要素 elHeader_ にアタッチします。goog.events.listen() の呼び出しにより、ユーザーが elHeader_ をクリックすると、ハンドラ関数 onHeaderClick_ がトリガーされます。この呼び出しの他の引数については、イベント チュートリアルをご覧ください。

goog.events.listen() を使用して独自のコードでブラウザ イベントを処理することで、異なるブラウザのイベント システム用に特殊なケースを作成する必要がなくなります。

goog.events.listen() を使用して Closure Library クラスのインスタンスをリッスンすることもできます。たとえば Closure Library のクラス goog.ui.Zippy は、Zippy が開かれたときに下記のカスタム イベントをディスパッチします。

  this.dispatchEvent(new goog.ui.ZippyEvent(goog.ui.Zippy.Events.TOGGLE,
      this, this.expanded_));

このイベントをリッスンすると、次に示すように、たとえばユーザーにアラートを送信するなど、コードでこのイベントに対応できます。

  var zippyHeader = document.getElementById('header');
  var zippyContent = document.getElementById('content');
  var zippy = new goog.ui.Zippy(zippyHeader, zippyContent);

  function react(e) {
    alert('The Zippy opened!');
  }
  goog.events.listen(zippy, goog.ui.Zippy.Events.TOGGLE, react);

クロージャ ライブラリのイベントの詳細については、イベント チュートリアルをご覧ください。