[インデックス 16688] ファイルの概要
このコミットは、doc/godocs.js
と lib/godoc/package.html
の2つのファイルを変更しています。これらはGo言語の公式ドキュメントサイト golang.org
における、Goコードの例(Example)の表示と実行機能に関連するファイルです。
doc/godocs.js
:golang.org
のドキュメントページで利用されるJavaScriptファイルで、UIのインタラクションや動的なコンテンツの挙動を制御します。特に、トグル可能なセクションの表示/非表示や、Go Playgroundの初期化に関わっています。lib/godoc/package.html
:godoc
ツールがパッケージドキュメントを生成する際に使用するHTMLテンプレートです。Goのパッケージドキュメントページ(例:golang.org/pkg/strings/
)の構造とコンテンツを定義しており、Goコードの例を埋め込む部分が含まれます。
コミット
このコミットは、golang.org
上でGoのExampleコードに直接リンクした場合に、そのExampleが正しく表示されず、Go Playgroundで実行できない問題を修正します。具体的には、Exampleセクションが既に表示されている場合でも、Go Playgroundが適切にセットアップされるようにJavaScriptのロジックを調整しています。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/493538adbfc5a580f9c5c92e2789769a7237e19a
元コミット内容
commit 493538adbfc5a580f9c5c92e2789769a7237e19a
Author: Andrew Gerrand <adg@golang.org>
Date: Tue Jul 2 08:44:25 2013 +1000
cmd/godoc: set up playground for examples that are already visible
This fixes an issue where linking directly to an example makes it not
runnable and visible only in a tiny window. To see the bug in action,
visit this link: http://golang.org/pkg/strings/#example_Map
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/10679050
変更の背景
Go言語の公式ドキュメントサイト golang.org
では、各パッケージのドキュメントページにGoコードのExampleが埋め込まれており、これらはGo Playgroundと連携してブラウザ上で直接実行できるようになっています。通常、これらのExampleは初期状態では折りたたまれており、ユーザーが「Example」セクションをクリックして展開すると、Go Playgroundが初期化され、コードが表示・実行可能になります。
しかし、このコミットが修正しようとしている問題は、特定のExampleに直接リンク(例: http://golang.org/pkg/strings/#example_Map
のようにURLのフラグメント識別子 #
を使ってExampleのIDを指定)した場合に発生していました。この直接リンクによってページがロードされると、ブラウザは指定されたExampleセクションまでスクロールしますが、そのセクションは「既に表示されている」と認識されるため、通常Exampleを展開する際にトリガーされるGo Playgroundの初期化ロジックが実行されませんでした。結果として、Exampleコードは小さなウィンドウに表示されるだけで、Go Playgroundの実行ボタンや出力領域が表示されず、コードを実行できない状態になっていました。
この問題はユーザーエクスペリエンスを著しく損なうものであり、Exampleへのディープリンクの有用性を低下させていました。
前提知識の解説
godoc
godoc
はGo言語の公式ツールの一つで、Goのソースコードからドキュメントを生成し、HTTPサーバーとして提供する機能を持っています。golang.org
のドキュメントサイトも、この godoc
ツールによって生成されたコンテンツを基盤としています。godoc
は、Goのソースコード内のコメントやExampleコードを解析し、整形されたHTMLドキュメントとして出力します。
Go Playground
Go Playgroundは、Go言語のコードをブラウザ上で記述、コンパイル、実行できるオンラインサービスです。golang.org
のExampleコードは、このGo Playgroundの機能を利用して、ユーザーがブラウザ上で直接コードを試せるようになっています。Go Playgroundは、ユーザーが入力したコードをGoogleのサーバー上で安全に実行し、その結果をブラウザに返します。
HTMLのフラグメント識別子(#ハッシュ)
URLの末尾に #
とそれに続く文字列(フラグメント識別子)がある場合、ブラウザはその識別子に対応するIDを持つHTML要素までページをスクロールします。例えば、http://example.com/page.html#section2
というURLは、page.html
内の id="section2"
を持つ要素までスクロールします。この機能は、ページ内の特定の部分に直接リンクするために広く使われています。
jQueryの .toggle()
と .click()
このコミットのコードでは、JavaScriptライブラリであるjQueryが使用されています。
.toggle()
: 要素の表示/非表示を切り替えるメソッドです。.click()
: 要素がクリックされたときに実行されるイベントハンドラを設定するメソッドです。.is(':visible')
: 要素が現在表示されているかどうかを判定するセレクタです。.find('.toggleButton').first().click()
: 特定の要素(.toggle
クラスを持つ要素)の中から、.toggleButton
クラスを持つ最初の子要素を見つけ、その要素に対してプログラム的にクリックイベントを発生させます。
技術的詳細
このコミットの修正は、主に lib/godoc/package.html
内のJavaScriptロジックと、doc/godocs.js
の小さな変更によって構成されています。
lib/godoc/package.html
の変更
以前のバージョンでは、Go Playgroundのセットアップは、Exampleコードを含む div.play
要素の親である .toggle
クラスを持つ要素がクリックされたときにのみ実行されるようになっていました。このロジックは以下のようでした。
// Old logic
$('div.play').each(function (i, el) {
var built = false;
$(el).closest('.toggle').click(function() {
if (built) {
return;
}
built = true;
// Set up playground.
// ... playground setup code ...
});
});
このコミックでは、このロジックが以下のように変更されました。
-
setup
関数への抽出: Go Playgroundの初期化ロジックがsetup
という名前の関数に抽出されました。これにより、コードの再利用性が向上し、異なる条件で同じセットアップ処理を呼び出すことが可能になりました。var setup = function() { var code = $('.code', el); playground({ 'codeEl': code, // ... other playground options ... }); // ... resize logic ... };
-
初期表示時のGo Playgroundセットアップ: ページロード時にExampleセクションが既に表示されている(つまり、直接リンクによって表示された)場合、
setup()
関数を直ちに呼び出すように変更されました。これは$(el).is(':visible')
を使って判定されます。if ($(el).is(':visible')) { setup(); return; // 既にセットアップされたので、以降のクリックイベントハンドラは不要 }
-
クリックイベントハンドラの維持: Exampleが初期表示されていない(通常の状態)場合は、以前と同様に
.toggle
要素がクリックされたときにsetup()
関数が呼び出されるように、クリックイベントハンドラが設定されます。ただし、built
フラグを使って、セットアップが一度だけ行われるように制御されています。var built = false; $(el).closest('.toggle').click(function() { if (!built) { setup(); built = true; } });
この変更により、Exampleが直接リンクによって表示された場合でも、$(el).is(':visible')
の条件が真となり、setup()
関数が即座に実行されるため、Go Playgroundが正しく初期化され、Exampleコードが実行可能になります。
doc/godocs.js
の変更
doc/godocs.js
の toggleHash()
関数も変更されています。この関数は、URLのハッシュ(フラグメント識別子)に基づいて、対応する要素の表示状態を調整する役割を担っています。
以前のコードでは、ハッシュに対応する要素が .toggle
クラスを持っている場合、その要素に toggleVisible
クラスを追加し、.toggle
クラスを削除していました。
// Old logic
if (hash.is('.toggle')) {
hash.addClass('toggleVisible').removeClass('toggle');
}
新しいコードでは、この部分が以下のように変更されました。
// New logic
if (hash.is('.toggle')) {
hash.find('.toggleButton').first().click();
}
この変更は、直接リンクされたExampleセクションが toggle
クラスを持つ場合、そのセクション内の最初の .toggleButton
要素に対してプログラム的にクリックイベントを発生させることを意味します。これにより、lib/godoc/package.html
で定義されたクリックイベントハンドラがトリガーされ、Go Playgroundのセットアップロジックが実行されるようになります。これは、lib/godoc/package.html
の変更と連携して、Exampleが直接リンクされた際にGo Playgroundが正しく初期化されることを保証します。
コアとなるコードの変更箇所
doc/godocs.js
--- a/doc/godocs.js
+++ b/doc/godocs.js
@@ -182,7 +182,7 @@ function fixFocus() {
function toggleHash() {
var hash = $(window.location.hash);\n if (hash.is('.toggle')) {
- hash.addClass('toggleVisible').removeClass('toggle');
+ hash.find('.toggleButton').first().click();
}
}
lib/godoc/package.html
--- a/lib/godoc/package.html
+++ b/lib/godoc/package.html
@@ -231,15 +231,8 @@ $(document).ready(function() {
'use strict';
// Set up playground when each element is toggled.
$('div.play').each(function (i, el) {
-\t\tvar built = false;
-\t\t$(el).closest('.toggle').click(function() {
-\t\t\t// Only set up playground once.
-\t\t\tif (built) {
-\t\t\t\treturn;
-\t\t\t}
-\t\t\tbuilt = true;
-\n-\t\t\t// Set up playground.
+\t\t// Set up playground for this example.
+\t\tvar setup = function() {
\t\t\tvar code = $('.code', el);
\t\t\tplayground({
\t\t\t\t'codeEl': code,
@@ -260,6 +253,22 @@ $(document).ready(function() {
\t\t\tcode.on('keydown', resize);
\t\t\tcode.on('keyup', resize);
\t\t\tcode.keyup(); // resize now.
+\t\t};\n+\t\t
+\t\t// If example already visible, set up playground now.\n+\t\tif ($(el).is(':visible')) {
+\t\t\tsetup();
+\t\t\treturn;\n+\t\t}
+\n+\t\t// Otherwise, set up playground when example is expanded.\n+\t\tvar built = false;\n+\t\t$(el).closest('.toggle').click(function() {
+\t\t\t// Only set up once.\n+\t\t\tif (!built) {
+\t\t\t\tsetup();
+\t\t\t\tbuilt = true;\n+\t\t\t}
\t\t});
\t});
});
コアとなるコードの解説
doc/godocs.js
の変更
toggleHash()
関数内の変更は、URLのハッシュによって特定のExampleセクションに直接アクセスした場合の挙動を改善します。
hash.addClass('toggleVisible').removeClass('toggle');
からhash.find('.toggleButton').first().click();
へ:- 以前のコードは、ハッシュで指定された要素(Exampleセクション)が
.toggle
クラスを持っている場合、その要素の表示状態を直接変更していました。しかし、これだけではGo Playgroundの初期化に必要なJavaScriptイベントがトリガーされませんでした。 - 新しいコードでは、ハッシュで指定されたExampleセクション内の「トグルボタン」(通常はExampleの表示/非表示を切り替えるためのボタン)をプログラム的にクリックします。この「クリック」によって、
lib/godoc/package.html
で設定されているクリックイベントハンドラが発火し、Go Playgroundのセットアップロジックが実行されるようになります。これにより、直接リンクされたExampleでもGo Playgroundが正しく機能するようになります。
- 以前のコードは、ハッシュで指定された要素(Exampleセクション)が
lib/godoc/package.html
の変更
このファイルでは、各Example (div.play
) のGo Playgroundセットアップロジックが大幅に改善されています。
-
Go Playgroundセットアップロジックの
setup
関数への抽出:- 以前は、Go Playgroundの初期化コードがクリックイベントハンドラ内に直接記述されていました。
- 新しいコードでは、この初期化ロジックが
setup
という独立した関数にまとめられました。これにより、コードの可読性が向上し、同じセットアップロジックを複数の場所から呼び出すことが容易になります。
-
if ($(el).is(':visible')) { setup(); return; }
の追加:- これがこのコミットの最も重要な変更点です。ページがロードされた時点で、Exampleセクション (
el
) が既に表示されているかどうか (:visible
) をチェックします。 - もし表示されていれば(これはURLのハッシュによって直接リンクされた場合に発生します)、
setup()
関数を直ちに呼び出してGo Playgroundを初期化します。 return;
によって、このExampleに対する以降のクリックイベントハンドラの設定をスキップします。これは、既にセットアップが完了しているため、クリックイベントを待つ必要がないからです。
- これがこのコミットの最も重要な変更点です。ページがロードされた時点で、Exampleセクション (
-
クリックイベントハンドラの変更:
- Exampleが初期表示されていない場合(通常のドキュメント閲覧時)、以前と同様に
.toggle
要素がクリックされたときにsetup()
関数が呼び出されるようにイベントハンドラが設定されます。 if (!built)
チェックは、setup()
関数が一度だけ実行されることを保証します。これにより、ユーザーがExampleセクションを複数回クリックしても、Go Playgroundが不必要に再初期化されるのを防ぎます。
- Exampleが初期表示されていない場合(通常のドキュメント閲覧時)、以前と同様に
これらの変更により、golang.org
のExample機能は、直接リンクされた場合でも、ユーザーが手動で展開した場合でも、一貫してGo Playgroundが正しく機能するようになりました。
関連リンク
- Go CL 10679050: https://golang.org/cl/10679050
参考にした情報源リンク
- GitHubコミットページ: https://github.com/golang/go/commit/493538adbfc5a580f9c5c92e2789769a7237e19a
- Go Playground: https://go.dev/play/
- godoc: https://pkg.go.dev/cmd/godoc
- jQuery
.is(':visible')
ドキュメント: https://api.jquery.com/visible-selector/ - jQuery
.find()
ドキュメント: https://api.jquery.com/find/ - jQuery
.click()
ドキュメント: https://api.jquery.com/click/