[インデックス 14122] ファイルの概要
このコミットは、Go言語の公式ドキュメントツールであるgodoc
のウェブインターフェースに組み込まれているGo Playgroundウィジェットにおいて、「おもちゃ」(toy)と呼ばれる事前定義されたコード例を選択する機能を復元するものです。具体的には、ユーザーがドロップダウンメニューからGoのコード例を選択し、それをPlaygroundに読み込んで実行できるようにする機能が修正されています。
コミット
- コミットハッシュ:
bd31e62982461b9b5b10b8c2181eff56fe4085f9
- 作者: Andrew Gerrand adg@golang.org
- コミット日時: 2012年10月11日 木曜日 09:53:37 +1100
- 変更ファイル:
doc/play/playground.js
doc/root.html
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bd31e62982461b9b5b10b8c2181eff56fe4085f9
元コミット内容
godoc: restore toy selection to playground widget
Fixes #4225.
R=golang-dev
CC=golang-dev
https://golang.org/cl/6640054
変更の背景
このコミットの目的は、godoc
のGo Playgroundウィジェットから失われていた「おもちゃ」(toy)選択機能を復元することです。コミットメッセージにある「restore」という言葉と「Fixes #4225」という記述から、以前は存在していたこの機能が何らかの理由で動作しなくなっていたか、削除されていたことが推測されます。Issue #4225は、この機能の不具合や欠如を報告していたものと考えられます。
「おもちゃ」機能は、ユーザーがGo PlaygroundでGo言語の様々な機能やライブラリの動作を簡単に試せるように、あらかじめ用意されたコード例(例えば、特定のパッケージの使用例やアルゴリズムの実装例など)を提供します。これにより、ユーザーは手動でコードを入力する手間を省き、迅速にGo言語の挙動を学習・確認することができます。この機能が失われたことでユーザー体験が損なわれていたため、本コミットでその利便性を回復することが図られました。
前提知識の解説
Go Playground
Go Playgroundは、Go言語のプログラムをウェブブラウザ上で実行できるサンドボックス環境を提供するサービスです。go.dev
などの公式ウェブサイトや、godoc
のウェブインターフェースに組み込まれて利用されます。ユーザーはGoのコードを記述し、「Run」ボタンをクリックすることで、サーバーサイドでそのコードがコンパイル・実行され、結果がブラウザに表示されます。これにより、Go言語の学習や簡単なコードのテストを、ローカル環境のセットアップなしに行うことができます。
godoc
godoc
は、Go言語のソースコードからドキュメントを生成するためのツールです。Goのパッケージ、関数、型、変数などの定義とコメントを解析し、HTML形式のドキュメントとして出力します。また、godoc -http
コマンドを使用することで、ローカルにドキュメントサーバーを立ち上げることができます。このサーバーは、Goの標準ライブラリやユーザーが作成したパッケージのドキュメントをブラウザで閲覧可能にするだけでなく、-play
フラグを付与することで、ドキュメント内のコード例をGo Playgroundで実行できる機能(Playgroundウィジェット)を提供します。
AJAX (Asynchronous JavaScript and XML)
AJAXは、ウェブページ全体をリロードすることなく、非同期でサーバーとデータをやり取りするための技術の総称です。JavaScriptのXMLHttpRequest
オブジェクト(またはfetch
API)を使用して、バックグラウンドでサーバーにリクエストを送信し、レスポンスを受け取ります。これにより、ウェブアプリケーションはよりインタラクティブで応答性の高いユーザーインターフェースを提供できます。本コミットでは、ユーザーが「おもちゃ」を選択した際に、そのコード内容をサーバーから非同期で取得するためにAJAXが利用されています。
HTML select
要素とJavaScriptイベントハンドリング
HTMLの<select>
要素は、ドロップダウンリストを作成するために使用されます。ユーザーはこのリストから一つのオプションを選択できます。JavaScriptでは、この<select>
要素に対してchange
イベントリスナーを登録することができます。ユーザーがドロップダウンリストの選択を変更すると、このchange
イベントが発火し、登録されたJavaScript関数が実行されます。本コミットでは、このメカニズムを利用して、ユーザーが「おもちゃ」を選択したときに、対応するGoコードをPlaygroundに読み込む処理をトリガーしています。
jQuery
変更されたplayground.js
ファイル内の$
記号は、JavaScriptライブラリであるjQueryが使用されていることを示唆しています。jQueryは、HTMLドキュメントの走査、イベントハンドリング、アニメーション、AJAXなどの操作を、より簡単かつクロスブラウザ互換性のある方法で記述できるようにするライブラリです。
技術的詳細
このコミットの主要な変更は、doc/play/playground.js
に「おもちゃ」選択機能のロジックを追加し、doc/root.html
から関連する古い設定を削除することです。
playground.js
は、Go Playgroundウィジェットのクライアントサイドの動作を制御するJavaScriptファイルです。このファイルは、Playgroundの初期化時に渡されるopts
オブジェクトを通じて、コードエディタ、出力表示エリア、実行ボタンなどのHTML要素への参照を受け取ります。
本コミットでは、opts
オブジェクトに新たにtoysEl
というオプションが追加されました。これは、ユーザーが「おもちゃ」を選択するためのHTMLの<select>
要素への参照を期待します。
追加されたJavaScriptコードは、以下のロジックを実装しています。
opts['toysEl']
が存在するか(つまり、toysEl
オプションが渡されているか)を確認します。- もし
toysEl
が存在すれば、その要素に対してchange
イベントリスナーをバインドします。 - ユーザーが
toysEl
(ドロップダウンリスト)の選択を変更すると、change
イベントが発火し、以下の処理が実行されます。 a. 選択された「おもちゃ」の値(例:hello.go
)を取得します。 b. jQueryの$.ajax
関数を使用して、サーバーに対して非同期HTTP GETリクエストを送信します。リクエストのURLは、選択された「おもちゃ」の値に基づいて動的に構築されます(例:/doc/play/hello.go
)。 c. サーバーからのレスポンスが完了すると、complete
コールバック関数が実行されます。 d. HTTPステータスコードが200(成功)であれば、レスポンスのテキスト(Goコードの内容)をsetBody
関数に渡して、Playgroundのコードエディタの内容を更新します。 e. ステータスコードが200以外であれば、「Server error; try again.」というアラートメッセージを表示します。
一方、doc/root.html
からは、以下の変更が行われました。
<script type="text/javascript" src="/doc/play/playground.js"></script>
という行が削除されました。これは、playground.js
がroot.html
に直接インクルードされなくなったことを意味します。しかし、playground
関数は引き続きroot.html
内で呼び出されているため、playground.js
は別のメカニズム(例えば、別のJavaScriptファイルからの動的ロードや、ビルドプロセスによるバンドルなど)でロードされることが前提となっていると考えられます。playground
関数の初期化オプションから"simple": true,
が削除されました。これは、おそらく「おもちゃ」選択機能の導入により、以前の「シンプル」モードが不要になったか、あるいは「おもちゃ」機能がその役割を包含するようになったためと考えられます。
これらの変更により、godoc
のウェブインターフェースに表示されるGo Playgroundは、ユーザーが簡単にGoのコード例を読み込み、実行できる機能を取り戻しました。
コアとなるコードの変更箇所
diff --git a/doc/play/playground.js b/doc/play/playground.js
index 3f766a9bf1..0f56fc0564 100644
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -3,13 +3,14 @@
// license that can be found in the LICENSE file.\n \n // opts is an object with these keys\n-// \tcodeEl - code editor element\n-// \toutputEl - program output element\n+//\tcodeEl - code editor element\n+//\toutputEl - program output element\n //\trunEl - run button element\n-// \tfmtEl - fmt button element (optional)\n-// \tshareEl - share button element (optional)\n-// \tshareURLEl - share URL text input element (optional)\n-// \tshareRedirect - base URL to redirect to on share (optional)\n+//\tfmtEl - fmt button element (optional)\n+//\tshareEl - share button element (optional)\n+//\tshareURLEl - share URL text input element (optional)\n+//\tshareRedirect - base URL to redirect to on share (optional)\n+//\ttoysEl - toys select element (optional)\n //\tenableHistory - enable using HTML5 history API (optional)\n function playground(opts) {\n \tvar code = $(opts[\'codeEl\']);\n@@ -226,4 +227,21 @@ function playground(opts) {\n \t\t\t});\n \t\t});\n \t}\n+\n+\tif (opts[\'toysEl\'] != null) {\n+\t\t$(opts[\'toysEl\']).bind(\'change\', function() {\n+\t\t\tvar toy = $(this).val();\n+\t\t\t$.ajax(\"/doc/play/\"+toy, {\n+\t\t\t\tprocessData: false,\n+\t\t\t\ttype: \"GET\",\n+\t\t\t\tcomplete: function(xhr) {\n+\t\t\t\t\tif (xhr.status != 200) {\n+\t\t\t\t\t\talert(\"Server error; try again.\")\n+\t\t\t\t\t\treturn;\n+\t\t\t\t\t}\n+\t\t\t\t\tsetBody(xhr.responseText);\n+\t\t\t\t}\n+\t\t\t});\n+\t\t});\n+\t}\n }\ndiff --git a/doc/root.html b/doc/root.html
index 3b4b43a5e0..cc2bfd1ba9 100644
--- a/doc/root.html
+++ b/doc/root.html
@@ -85,7 +85,6 @@ Linux, Mac OS X, Windows, and more.\n <div style=\"clear: both;\"></div>\n \n <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n-<script type=\"text/javascript\" src=\"/doc/play/playground.js\"></script>\n <script type=\"text/javascript\">\n google.load(\"feeds\", \"1\");\n \n@@ -122,7 +121,6 @@ function init() {\n \n \t// Set up playground.\n \tplayground({\n-\t\t\"simple\": true,\n \t\t\"codeEl\": \"#learn .code\",\n \t\t\"outputEl\": \"#learn .output\",\n \t\t\"runEl\": \"#learn .run\",\n```
## コアとなるコードの解説
### `doc/play/playground.js` の変更点
1. **`opts` オブジェクトのドキュメント更新**:
`// opts is an object with these keys` のコメントブロックに、新しく `//\ttoysEl - toys select element (optional)` が追加されました。これは、`playground` 関数が初期化オプションとして `toysEl` というキーを受け取ることを明示しています。`toysEl` は、Go Playgroundに読み込む「おもちゃ」を選択するためのHTMLの`<select>`要素への参照を期待します。
2. **「おもちゃ」選択機能のロジック追加**:
ファイルの末尾に、以下の新しいコードブロックが追加されました。
```javascript
if (opts['toysEl'] != null) {
$(opts['toysEl']).bind('change', function() {
var toy = $(this).val();
$.ajax("/doc/play/"+toy, {
processData: false,
type: "GET",
complete: function(xhr) {
if (xhr.status != 200) {
alert("Server error; try again.")
return;
}
setBody(xhr.responseText);
}
});
});
}
```
- `if (opts['toysEl'] != null)`: `playground` 関数が呼び出された際に、`toysEl` オプションが提供されているかどうかを確認します。これにより、この機能が必要な場合にのみコードが実行されます。
- `$(opts['toysEl']).bind('change', function() { ... });`: `toysEl` で指定されたHTML要素(おそらく`<select>`タグ)に対して、`change`イベントリスナーをバインドしています。ユーザーがドロップダウンリストの選択を変更すると、この関数が実行されます。
- `var toy = $(this).val();`: 選択されたオプションの`value`属性の値を取得し、`toy`変数に格納します。この値は、サーバーから取得するGoコードのファイル名(例: `hello.go`)に対応すると考えられます。
- `$.ajax("/doc/play/"+toy, { ... });`: jQueryの`$.ajax`関数を使用して、サーバーに非同期リクエストを送信します。
- `url`: `"/doc/play/"+toy` という形式で、選択された「おもちゃ」のGoコードを取得するためのURLを構築します。例えば、`toy`が`hello.go`であれば、`/doc/play/hello.go`にリクエストが送られます。
- `processData: false`: データ処理を行わない設定です。GETリクエストなので通常は不要ですが、明示的に指定されています。
- `type: "GET"`: HTTP GETメソッドでリクエストを送信することを指定します。
- `complete: function(xhr) { ... }`: リクエストが完了した際に実行されるコールバック関数です。`xhr`オブジェクトには、HTTPレスポンスに関する情報が含まれます。
- `if (xhr.status != 200)`: HTTPステータスコードが200(OK)以外の場合、サーバーエラーが発生したと判断し、`alert("Server error; try again.")`でユーザーにエラーメッセージを表示し、処理を中断します。
- `setBody(xhr.responseText);`: ステータスコードが200であれば、サーバーからのレスポンスボディ(取得したGoコードのテキスト)を`setBody`関数に渡します。`setBody`関数は、Playgroundのコードエディタの内容を更新する役割を担っていると推測されます。
### `doc/root.html` の変更点
1. **`playground.js` のスクリプトタグ削除**:
`<script type="text/javascript" src="/doc/play/playground.js"></script>` の行が削除されました。これは、`root.html`が直接`playground.js`を読み込まなくなったことを意味します。しかし、`root.html`の後半で`playground({...})`関数が引き続き呼び出されているため、`playground.js`は別の方法(例えば、別のJavaScriptファイルが依存関係として読み込む、またはビルドプロセスでバンドルされるなど)でロードされることが前提となっています。
2. **`playground` 初期化オプションからの `"simple": true` 削除**:
`playground` 関数の初期化ブロックから、`"simple": true,` の行が削除されました。
```diff
- "simple": true,
"codeEl": "#learn .code",
"outputEl": "#learn .output",
"runEl": "#learn .run",
```
この`"simple": true`オプションの具体的な機能は不明ですが、「おもちゃ」選択機能の復元に伴い、その役割が不要になったか、あるいは「おもちゃ」機能がより包括的なコード例の提供方法として置き換わった可能性が考えられます。
これらの変更により、`godoc`のウェブインターフェースは、ユーザーがGo Playgroundで様々なGoコード例を簡単に試せるようになり、学習やデモンストレーションの利便性が向上しました。
## 関連リンク
- GitHubコミットページ: [https://github.com/golang/go/commit/bd31e62982461b9b5b10b8c2181eff56fe4085f9](https://github.com/golang/go/commit/bd31e62982461b9b5b10b8c2181eff56fe4085f9)
- Gerrit Change-ID: [https://golang.org/cl/6640054](https://golang.org/cl/6640054)
## 参考にした情報源リンク
- Go Playground: [https://go.dev/play/](https://go.dev/play/)
- godocコマンド: [https://go.dev/blog/godoc](https://go.dev/blog/godoc)
- Go Testable Examples: [https://go.dev/blog/examples](https://go.dev/blog/examples)
- Stack Overflow - How to enable Go Playground in godoc: [https://stackoverflow.com/questions/10900000/how-to-enable-go-playground-in-godoc](https://stackoverflow.com/questions/10900000/how-to-enable-go-playground-in-godoc)
- JetBrains YouTrack - GO-4225 (Name starts with package name inspection optimization): [https://youtrack.jetbrains.com/issue/GO-4225](https://youtrack.jetbrains.com/issue/GO-4225) (コミットメッセージの`Fixes #4225`はGoプロジェクト内部のIssueトラッカーを参照している可能性が高いですが、一般的な検索で関連性の高い情報としてJetBrainsのGoLand IDEのIssueも確認しました。)
- Google Search for "golang godoc playground widget"
- Google Search for "golang issue 4225"
- Google Search for "golang/go issue 4225"