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

[インデックス 13523] ファイルの概要

このコミットは、GoプロジェクトのコードレビューダッシュボードにおけるHTMLテンプレートのタグのネストに関する問題を修正するものです。具体的には、misc/dashboard/codereview/dashboard/front.goファイル内のHTMLテンプレートにおいて、<span>タグの閉じタグの位置が誤っていたために発生していた表示上の不具合を解消しています。

コミット

commit 3fe5f3353f8d163ae973d4454d71c691c143e19d
Author: David Symonds <dsymonds@golang.org>
Date:   Mon Jul 30 11:37:20 2012 +1000

    misc/dashboard/codereview: fix tag nesting.
    
    R=golang-dev, rsc, minux.ma
    CC=golang-dev
    https://golang.org/cl/6454062

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3fe5f3353f8d163ae973d4454d71c691c143e19d

元コミット内容

misc/dashboard/codereview: fix tag nesting.

変更の背景

この変更は、Goプロジェクトのコードレビューシステムで使用されるダッシュボードのフロントエンド表示に関するバグ修正です。ダッシュボードは、コードレビューのステータス(LGTM: Looks Good To Me、またはNOT LGTM)を表示する際に、HTMLの<span>タグを適切にネストしていませんでした。これにより、ブラウザでの表示が崩れたり、HTMLの構造が不正になったりする可能性がありました。

HTMLのタグのネストが正しくない場合、以下のような問題が発生する可能性があります。

  • 表示の崩れ: CSSの適用が意図しない範囲に及んだり、要素の配置がずれたりする。
  • アクセシビリティの低下: スクリーンリーダーなどの支援技術がページの構造を正しく解釈できなくなる。
  • JavaScriptの誤動作: DOM操作を行うJavaScriptが、期待する要素を見つけられなかったり、誤った要素を操作したりする。
  • HTMLバリデーションエラー: HTMLの標準に準拠していないため、将来的な互換性の問題や、開発ツールでの警告の原因となる。

このコミットは、これらの問題を回避し、ダッシュボードの表示を安定させるために行われました。

前提知識の解説

1. Go言語のhtml/templateパッケージ

Go言語には、HTMLコンテンツを安全に生成するためのhtml/templateパッケージがあります。このパッケージは、クロスサイトスクリプティング(XSS)攻撃を防ぐために、出力されるHTMLを自動的にエスケープする機能を持っています。テンプレートは、Goのデータ構造をHTMLに埋め込むためのプレースホルダーや制御構造(条件分岐、ループなど)を記述できます。

このコミットで修正されているのは、template.Must(template.New("front").Funcs(template.FuncMap{...}))で初期化されるテンプレートです。template.Mustは、テンプレートのパースに失敗した場合にパニックを発生させるヘルパー関数です。Funcsは、テンプレート内で使用できるカスタム関数を登録するために使われます。

2. HTMLのタグのネスト

HTMLでは、要素は特定のルールに従ってネスト(入れ子に)される必要があります。例えば、<span>タグはインライン要素であり、通常は他のインライン要素やテキストを内包します。ブロックレベル要素(例: <div>, <p>)の中にインライン要素を配置することはできますが、その逆はできません。また、タグは開いた順序と逆の順序で閉じられる必要があります。

例:

  • 正しいネスト: <div><span>テキスト</span></div>
  • 誤ったネスト: <span><div>テキスト</div></span> (インライン要素の中にブロック要素)
  • 誤ったネスト: <span>テキスト<div></span></div> (タグの閉じ順序が不正)

このコミットでは、<span>タグの閉じタグが、その<span>タグが内包すべきコンテンツの外側に配置されていたことが問題でした。

3. コードレビューシステムとLGTM/NOT LGTM

ソフトウェア開発において、コードレビューは品質保証の重要なプロセスです。開発者が書いたコードを他の開発者が確認し、改善点や潜在的なバグを指摘します。

  • LGTM (Looks Good To Me): コードレビューアがコードを承認し、マージしても問題ないと判断したことを示す一般的な略語です。
  • NOT LGTM: コードに問題があり、修正が必要であるため、承認できないことを示す略語です。

Goプロジェクトのコードレビューダッシュボードは、これらのLGTMやNOT LGTMのステータスを視覚的に表示し、開発者がレビューの進捗を把握できるようにするツールです。

技術的詳細

問題の箇所は、Goのhtml/templateで記述されたHTMLスニペットです。

変更前のコード:

      {{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}{{end}}</span>
      {{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}{{end}}</span>

この行では、{{if ...}}{{end}}というGoテンプレートの条件分岐構文が使用されています。LGTMsまたはNotLGTMsが存在し、かつ$tbl.Assignableが真の場合に、<br />タグと<span>タグで囲まれたコンテンツが表示されます。

問題は、<span>タグの閉じタグ</span>{{end}}の後に配置されている点です。これにより、{{end}}によって条件分岐が終了した後も<span>タグが開いたままになり、その後のHTML構造に影響を与えていました。

具体的には、LGTMsまたはNotLGTMsの条件が偽の場合、<span>タグは開かれませんが、</span>タグは常に存在することになります。これはHTMLの構文エラーであり、ブラウザがこれをどのように解釈するかは実装依存となり、予期せぬ表示の崩れを引き起こす可能性がありました。

コアとなるコードの変更箇所

--- a/misc/dashboard/codereview/dashboard/front.go
+++ b/misc/dashboard/codereview/dashboard/front.go
@@ -244,8 +244,8 @@ var frontPage = template.Must(template.New("front").Funcs(template.FuncMap{
      {{end}}\n
      <td>
        <a href="http://codereview.appspot.com/{{.Number}}/" title="{{ printf "%s" .Description}}">{{.Number}}: {{.FirstLineHTML}}</a>
-      {{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}{{end}}</span>
-      {{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}{{end}}</span>
+      {{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}</span>{{end}}
+      {{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}</span>{{end}}
      </td>
      <td title="Last modified">{{.ModifiedAgo}}</td>
      {{if $.IsAdmin}}<td><a href="/update-cl?cl={{.Number}}" title="Update this CL">&#x27f3;</a></td>{{end}}

コアとなるコードの解説

変更は非常にシンプルで、<span>タグの閉じタグ</span>の位置を{{end}}の前に移動させています。

変更後のコード:

      {{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}</span>{{end}}
      {{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}</span>{{end}}

この修正により、<span>タグは{{if ...}}{{end}}ブロックの内部に完全に含まれるようになりました。つまり、条件が真の場合にのみ<span>タグが開かれ、その直後に閉じられるため、HTMLのタグのネストが正しくなります。条件が偽の場合、<span>タグは一切出力されないため、不正な閉じタグが出力されることもなくなります。

この修正は、HTMLの構文規則に厳密に従うことで、ブラウザ間の互換性を高め、将来的なメンテナンス性を向上させるためのものです。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • HTMLの仕様に関する一般的な知識
  • Gitのコミットログと差分表示
  • GitHubのコミットページ