[インデックス 12114] ファイルの概要
このコミットは、Go言語の公式ウェブサイトにおけるGo Playgroundの共有機能に、新しいリダイレクトメカニズムを導入するものです。具体的には、ユーザーがコードを共有した際に、共有されたコードのURLを表示する代わりに、指定されたベースURLに共有コードのIDを付加して即座にリダイレクトする機能を追加します。これにより、Go Playgroundのメインサイト(play.golang.org)のような環境で、共有ボタンをクリックすると直接共有されたコードのページに遷移する、よりシームレスなユーザーエクスペリエンスが実現されます。
コミット
commit 1a1940c8703351ded9b16d29cefb79539b289088
Author: Andrew Gerrand <adg@golang.org>
Date: Wed Feb 22 09:16:54 2012 +1100
doc: support redirect-on-share
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5689056
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1a1940c8703351ded9b16d29cefb79539b289088
元コミット内容
doc: support redirect-on-share
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5689056
変更の背景
Go Playgroundは、Go言語のコードをブラウザ上で実行し、その結果を共有できる非常に便利なツールです。以前の共有機能では、ユーザーがコードを共有すると、そのコードへの永続的なURLが生成され、テキストボックスに表示されていました。ユーザーはそのURLをコピーして手動で共有する必要がありました。
しかし、Go Playgroundの主要な利用シナリオの一つとして、共有されたコードに直接アクセスしたいというニーズがあります。例えば、play.golang.org
のような公式のPlaygroundサイトでは、共有ボタンを押した後に、生成されたURLをユーザーが手動でコピーするのではなく、直接その共有されたコードがロードされたページにブラウザが遷移する方が、ユーザー体験として自然で効率的です。
このコミットは、このような「共有後の即時リダイレクト」という振る舞いを可能にすることで、Go Playgroundの共有機能の柔軟性とユーザービリティを向上させることを目的としています。これにより、Playgroundを組み込むウェブサイトが、共有後の動作をより細かく制御できるようになります。
前提知識の解説
このコミットの変更内容を理解するためには、以下の技術的知識が役立ちます。
- Go Playground: Go言語のコードをブラウザ上で実行し、その結果を共有できるウェブベースのツールです。サーバーサイドでGoコードを実行し、その出力をクライアントに返します。共有機能は、コードをサーバーに保存し、一意のIDを生成することで実現されます。
- JavaScript: ウェブページの動的な振る舞いを実装するためのプログラミング言語です。このコミットでは、クライアントサイドのロジック(ボタンクリックの処理、AJAXリクエスト、DOM操作、リダイレクト)にJavaScriptが使用されています。
- jQuery: JavaScriptライブラリの一つで、DOM操作、イベントハンドリング、アニメーション、AJAXなどを簡潔に記述するためのAPIを提供します。
playground.js
ファイルではjQueryが多用されています。 - AJAX (Asynchronous JavaScript and XML): ウェブページ全体をリロードすることなく、サーバーと非同期でデータをやり取りする技術です。Go Playgroundの共有機能では、ユーザーのコードをサーバーに送信し、共有IDを受け取るためにAJAXが使われます。
- HTTPリダイレクト: ウェブサーバーがクライアント(ブラウザ)に対して、要求されたリソースが別のURLに移動したことを伝えるメカニズムです。このコミットでは、JavaScriptの
window.location
プロパティを操作することで、クライアントサイドでのリダイレクトをプログラム的に実行しています。 - HTML DOM (Document Object Model): HTMLドキュメントの構造をオブジェクトとして表現し、JavaScriptなどのスクリプト言語からその構造や内容、スタイルを動的に操作するためのAPIです。
doc/root.html
はHTMLドキュメントであり、playground.js
はそのDOM要素を操作します。
技術的詳細
このコミットの主要な変更点は、playground.js
にshareRedirect
という新しいオプションが追加されたことです。
-
playground
関数のオプション拡張:playground
関数は、Go Playgroundのフロントエンドロジックをカプセル化するJavaScript関数です。この関数に、新たにshareRedirect
というオプションが追加されました。このオプションは、共有が成功した際にブラウザをリダイレクトさせるためのベースURLを指定します。 -
共有機能の条件分岐の変更: 以前は、共有ボタン (
shareEl
) と共有URL表示要素 (shareURLEl
) の両方が存在する場合にのみ共有機能が有効になっていました。この変更により、shareURLEl
の代わりにshareRedirect
オプションが指定されている場合でも共有機能が有効になるように条件が拡張されました。 変更前:if (opts['shareEl'] == null || opts['shareURLEl'] == null)
変更後:if (opts['shareEl'] == null || (opts['shareURLEl'] == null && opts['shareRedirect'] == null))
これにより、shareURLEl
がなくてもshareRedirect
があれば共有機能が動作するようになります。 -
shareURL
変数の初期化の条件化:shareURL
変数は、共有されたURLを表示するテキスト入力要素を指します。この要素はshareURLEl
オプションが指定された場合にのみ存在するため、shareURL
の初期化もopts['shareURLEl']
が存在する場合にのみ行われるように変更されました。これにより、shareURLEl
が提供されない場合に不要なDOM操作やエラーを防ぎます。 -
共有成功時のリダイレクトロジックの追加: 共有リクエスト(AJAX POSTリクエスト)がサーバーから成功応答(HTTPステータス200)を受け取った際のコールバック関数に、新しいロジックが追加されました。
- もし
opts['shareRedirect']
が設定されている場合、window.location
プロパティが更新され、ブラウザはshareRedirect
で指定されたベースURLに、サーバーからの応答テキスト(これは共有されたコードの一意のIDであると想定されます)を結合したURLへ即座にリダイレクトされます。 shareURLEl
が設定されている場合は、以前と同様に生成された共有URLがテキストボックスに表示されます。この処理は、shareRedirect
によるリダイレクトとは排他的に動作します(つまり、リダイレクトが優先されます)。
- もし
-
doc/root.html
でのplayground
関数の呼び出し変更: Go Playgroundのメインページを構成するdoc/root.html
では、playground
関数を初期化する際に、shareURLEl
オプションを削除し、代わりにshareRedirect
オプションに"http://play.golang.org/"
を設定しています。これにより、play.golang.org
では共有ボタンをクリックすると、生成された共有IDを使ってhttp://play.golang.org/p/<shared_id>
のようなURLに直接リダイレクトされるようになります。
これらの変更により、Go Playgroundの共有機能は、共有URLの表示と即時リダイレクトという2つの異なる振る舞いをサポートするようになり、より多様なユースケースに対応できるようになりました。
コアとなるコードの変更箇所
doc/play/playground.js
--- a/doc/play/playground.js
+++ b/doc/play/playground.js
@@ -8,6 +8,7 @@
// runEl - run button element
// shareEl - share button element (optional)
// shareURLEl - share URL text input element (optional)
+// shareRedirect - base URL to redirect to on share (optional)
// preCompile - callback to mutate request data before compiling
// postCompile - callback to read response data after compiling
// simple - use plain textarea instead of CodeMirror.
@@ -163,7 +164,7 @@ function playground(opts) {
}
$(opts['runEl']).click(run);
- if (opts['shareEl'] == null || opts['shareURLEl'] == null) {
+ if (opts['shareEl'] == null || (opts['shareURLEl'] == null && opts['shareRedirect'] == null)) {
return editor;
}
@@ -171,7 +172,10 @@ function playground(opts) {
return (""+href).split("/").slice(0, 3).join("/");
}
- var shareURL = $(opts['shareURLEl']).hide();
+ var shareURL;
+ if (opts['shareURLEl']) {
+ shareURL = $(opts['shareURLEl']).hide();
+ }
var sharing = false;
$(opts['shareEl']).click(function() {
if (sharing) return;
@@ -184,11 +188,16 @@ function playground(opts) {
sharing = false;
if (xhr.status != 200) {
alert("Server error; try again.");
- return
+ return;
+ }
+ if (opts['shareRedirect']) {
+ window.location = opts['shareRedirect'] + xhr.responseText;
+ }
+ if (shareURL) {
+ var url = origin(window.location) + "/p/" +
+ xhr.responseText;
+ shareURL.show().val(url).focus().select();
}
- var url = origin(window.location) + "/p/" +
- xhr.responseText;
- shareURL.show().val(url).focus().select();
}
});
});
doc/root.html
--- a/doc/root.html
+++ b/doc/root.html
@@ -113,12 +113,12 @@ function init() {
// Set up playground.
playground({
- "simple": true,
- "codeEl": "#code",
- "outputEl": "#output",
- "runEl": "#run",
- "shareEl": "#share",
- "shareURLEl": "#shareURL"
+ "simple": true,
+ "codeEl": "#code",
+ "outputEl": "#output",
+ "runEl": "#run",
+ "shareEl": "#share",
+ "shareRedirect": "http://play.golang.org/"
});
}
コアとなるコードの解説
doc/play/playground.js
-
playground
関数のオプション定義の更新:// shareRedirect - base URL to redirect to on share (optional)
この行は、playground
関数が受け入れるオプションにshareRedirect
が追加されたことを示すドキュメントコメントです。これは、共有後にリダイレクトする際のベースURLを指定するために使用されます。 -
共有機能有効化の条件変更:
if (opts['shareEl'] == null || (opts['shareURLEl'] == null && opts['shareRedirect'] == null))
この条件文は、共有ボタン (shareEl
) が存在しない場合、または共有URL表示要素 (shareURLEl
) もリダイレクトURL (shareRedirect
) もどちらも指定されていない場合に、共有機能を無効にして早期にeditor
オブジェクトを返します。これにより、共有機能が適切に設定されていない場合に、関連するロジックが実行されないようにします。 -
shareURL
変数の条件付き初期化:var shareURL; if (opts['shareURLEl']) { shareURL = $(opts['shareURLEl']).hide(); }
以前は
shareURL
が常に初期化されていましたが、この変更により、shareURLEl
オプションが実際に提供されている場合にのみ、対応するDOM要素がjQueryオブジェクトとして取得され、非表示にされます。これは、shareURLEl
が不要な場合にDOM操作をスキップし、エラーを防ぐための最適化です。 -
共有成功時のリダイレクトロジック:
if (xhr.status != 200) { alert("Server error; try again."); return; } if (opts['shareRedirect']) { window.location = opts['shareRedirect'] + xhr.responseText; } if (shareURL) { var url = origin(window.location) + "/p/" + xhr.responseText; shareURL.show().val(url).focus().select(); }
これは、共有リクエストが成功した後の最も重要な変更点です。
- まず、サーバーからの応答ステータスが200(OK)でない場合は、エラーメッセージを表示して処理を中断します。
- 次に、
opts['shareRedirect']
が設定されているかどうかをチェックします。もし設定されていれば、window.location
プロパティを更新することで、ブラウザを新しいURLにリダイレクトします。新しいURLは、shareRedirect
のベースURLと、サーバーから返された共有コードのID(xhr.responseText
)を結合したものです。このリダイレクトが発生すると、以降のJavaScriptコードは実行されず、ページが完全に遷移します。 shareRedirect
によるリダイレクトが行われなかった場合(つまり、shareRedirect
が設定されていない場合)、shareURL
(共有URL表示要素)が存在するかどうかをチェックします。存在する場合、以前と同様に、生成された共有URL(origin(window.location) + "/p/" + xhr.responseText
)をテキストボックスに設定し、表示し、フォーカスして選択状態にします。
doc/root.html
playground
関数の初期化オプションの変更:
この変更は、- "shareURLEl": "#shareURL" + "shareRedirect": "http://play.golang.org/"
doc/root.html
(Go Playgroundのメインページ)が、共有URLをテキストボックスに表示する代わりに、共有後にhttp://play.golang.org/
をベースとしたURLにリダイレクトするように設定されたことを示しています。これにより、ユーザーがGo Playgroundでコードを共有すると、自動的にその共有されたコードのページに遷移するようになります。
これらの変更により、Go Playgroundの共有機能は、共有後の動作をより柔軟に制御できるようになり、特に公式のPlaygroundサイトでのユーザー体験が向上しました。
関連リンク
- Go Playground: https://play.golang.org/
- Go言語公式ウェブサイト: https://golang.org/
- Go Playgroundのソースコード(関連リポジトリ): https://github.com/golang/go/tree/master/doc/play
参考にした情報源リンク
- GitHubコミットページ: https://github.com/golang/go/commit/1a1940c8703351ded9b16d29cefb79539b289088
- Go Code Review (Gerrit) CL: https://golang.org/cl/5689056
- jQuery公式ドキュメント: https://jquery.com/
- MDN Web Docs (JavaScript, DOM, window.location): https://developer.mozilla.org/ja/docs/Web