Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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.jsshareRedirectという新しいオプションが追加されたことです。

  1. playground関数のオプション拡張: playground関数は、Go Playgroundのフロントエンドロジックをカプセル化するJavaScript関数です。この関数に、新たにshareRedirectというオプションが追加されました。このオプションは、共有が成功した際にブラウザをリダイレクトさせるためのベースURLを指定します。

  2. 共有機能の条件分岐の変更: 以前は、共有ボタン (shareEl) と共有URL表示要素 (shareURLEl) の両方が存在する場合にのみ共有機能が有効になっていました。この変更により、shareURLElの代わりにshareRedirectオプションが指定されている場合でも共有機能が有効になるように条件が拡張されました。 変更前: if (opts['shareEl'] == null || opts['shareURLEl'] == null) 変更後: if (opts['shareEl'] == null || (opts['shareURLEl'] == null && opts['shareRedirect'] == null)) これにより、shareURLElがなくてもshareRedirectがあれば共有機能が動作するようになります。

  3. shareURL変数の初期化の条件化: shareURL変数は、共有されたURLを表示するテキスト入力要素を指します。この要素はshareURLElオプションが指定された場合にのみ存在するため、shareURLの初期化もopts['shareURLEl']が存在する場合にのみ行われるように変更されました。これにより、shareURLElが提供されない場合に不要なDOM操作やエラーを防ぎます。

  4. 共有成功時のリダイレクトロジックの追加: 共有リクエスト(AJAX POSTリクエスト)がサーバーから成功応答(HTTPステータス200)を受け取った際のコールバック関数に、新しいロジックが追加されました。

    • もしopts['shareRedirect']が設定されている場合、window.locationプロパティが更新され、ブラウザはshareRedirectで指定されたベースURLに、サーバーからの応答テキスト(これは共有されたコードの一意のIDであると想定されます)を結合したURLへ即座にリダイレクトされます。
    • shareURLElが設定されている場合は、以前と同様に生成された共有URLがテキストボックスに表示されます。この処理は、shareRedirectによるリダイレクトとは排他的に動作します(つまり、リダイレクトが優先されます)。
  5. 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();
    }
    

    これは、共有リクエストが成功した後の最も重要な変更点です。

    1. まず、サーバーからの応答ステータスが200(OK)でない場合は、エラーメッセージを表示して処理を中断します。
    2. 次に、opts['shareRedirect']が設定されているかどうかをチェックします。もし設定されていれば、window.locationプロパティを更新することで、ブラウザを新しいURLにリダイレクトします。新しいURLは、shareRedirectのベースURLと、サーバーから返された共有コードのID(xhr.responseText)を結合したものです。このリダイレクトが発生すると、以降のJavaScriptコードは実行されず、ページが完全に遷移します。
    3. 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サイトでのユーザー体験が向上しました。

関連リンク

参考にした情報源リンク