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

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

このコミットは、Go言語のドキュメンテーションツールであるgodocが生成するHTMLページにおいて、id属性の一意性を確保するための修正です。特にInternet Explorer 9 (IE9)のような一部のブラウザがid属性の大文字・小文字を区別しないために発生する競合を回避するため、静的に定義されたid属性にpkg-プレフィックスを追加しています。また、トップレベルのインデックスに「Other packages」へのリンクが欠落していた問題も同時に修正されています。

コミット

commit 3601f27708e6c0d6f71e690139de46df19cedc38
Author: Robert Griesemer <gri@golang.org>
Date:   Tue Aug 7 17:45:58 2012 -0700

    godoc: make id attributes unique
    
    Some browsers (e.g. IE9) ignore the case of 'id' attributes
    which can lead to conflicts. Prefix non-generated 'id's with
    "pkg-" to make them different from any generated attribute.
    
    Also: Added missing entry for "Other packages" to top-level
    index.
    
    Fixes #3851.
    
    R=adg, dsymonds
    CC=golang-dev
    https://golang.org/cl/6449105

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

https://github.com/golang/go/commit/3601f27708e6c0d6f71e690139de46df19cedc38

元コミット内容

godoc: make id attributes unique

Some browsers (e.g. IE9) ignore the case of 'id' attributes
which can lead to conflicts. Prefix non-generated 'id's with
"pkg-" to make them different from any generated attribute.

Also: Added missing entry for "Other packages" to top-level
index.

Fixes #3851.

変更の背景

この変更の主な背景は、godocが生成するHTMLドキュメントにおけるid属性の競合問題です。HTMLの仕様では、id属性はドキュメント内で一意である必要があります。しかし、一部のブラウザ(特にInternet Explorer 9)は、id属性の大文字・小文字を区別せずに処理するという非標準的な挙動を示していました。

godocは、Goのソースコードからドキュメントを生成する際に、パッケージ名、関数名、変数名などから動的にid属性を生成します。一方で、HTMLテンプレート内には静的に定義されたid属性も存在します。IE9のようなブラウザでは、例えば動的に生成されたid="Foo"と静的に定義されたid="foo"が同じものとして扱われ、予期せぬ動作やリンクの不具合を引き起こす可能性がありました。

この問題を解決し、godocが生成するドキュメントのクロスブラウザ互換性を向上させることが、このコミットの目的です。また、関連する小さな修正として、トップレベルのパッケージインデックスに「Other packages」へのリンクが欠落していた点も修正されています。これは、ユーザーが関連する他のパッケージを容易に参照できるようにするための改善です。

前提知識の解説

HTMLのid属性

HTMLのid属性は、ドキュメント内の特定の要素を一意に識別するために使用されます。この属性の値は、HTMLドキュメント全体で重複してはならず、CSSで特定の要素にスタイルを適用したり、JavaScriptで特定の要素を操作したりする際のセレクタとして頻繁に利用されます。また、ページ内リンク(アンカーリンク)のターゲットとしても機能します。

HTML5の仕様では、id属性の値は「ドキュメント内で一意でなければならない」と明確に規定されています。また、id属性の値はASCII大文字・小文字を区別するとされています。

ブラウザの互換性問題(特にIE9のid属性の扱い)

ウェブ開発において、ブラウザ間の互換性問題は常に課題となります。特に古いブラウザや特定のベンダーのブラウザは、標準仕様に厳密に従わない独自の解釈やバグを持つことがありました。

Internet Explorer 9 (IE9)は、その一例です。IE9は、HTMLのid属性を処理する際に、大文字・小文字を区別しないという非標準的な挙動を示しました。例えば、id="MyElement"id="myelement"を同じものとして扱ってしまうため、開発者が意図しないidの競合が発生し、CSSの適用が意図しない要素に及んだり、JavaScriptでの要素選択が誤動作したりする可能性がありました。この挙動は、標準に準拠した他のブラウザ(Chrome, Firefoxなど)とは異なり、クロスブラウザ対応を困難にする要因の一つでした。

godocとは

godocは、Go言語の公式ドキュメンテーションツールです。Goのソースコードに記述されたコメント(特にエクスポートされた識別子に対するコメント)を解析し、HTML形式で整形されたドキュメントを自動生成します。これにより、開発者はコードとドキュメントを密接に連携させることができ、常に最新のドキュメントを維持しやすくなります。godocは、Goの標準ライブラリのドキュメント(pkg.go.devなどで公開されているもの)の生成にも利用されています。

godocは、Goのパッケージ構造を反映したナビゲーションや、関数、型、変数、定数などの詳細な情報を表示する機能を持ちます。また、コード例(Example関数)を自動的に実行し、その出力をドキュメントに含めることも可能です。

技術的詳細

このコミットの技術的解決策は、godocがHTMLドキュメントを生成する際に使用するテンプレートファイルlib/godoc/package.htmlを修正することによって実現されています。

具体的には、以下の2つの主要なアプローチが取られています。

  1. 静的id属性へのpkg-プレフィックスの追加: package.htmlテンプレート内でハードコードされている(つまり、Goのコードから動的に生成されるのではなく、テンプレートファイル自体に直接記述されている)すべてのid属性と、それらを参照するhref属性に対して、pkg-というプレフィックスが追加されました。 例えば、id="overview"id="pkg-overview"に、href="#overview"href="#pkg-overview"に変更されています。 このプレフィックスは、動的に生成される可能性のあるid属性(Goの識別子、例えば関数名や型名などから派生するもの)と、静的に定義されたid属性との間で、大文字・小文字を区別しないブラウザ環境下でも確実に競合が発生しないようにするためのものです。pkg-というプレフィックスは、それがパッケージドキュメントに関連する静的なIDであることを示唆しています。

  2. テンプレートコメントによる意図の明示: package.htmlファイルの冒頭に、このpkg-プレフィックスの導入意図を説明するHTMLコメントが追加されました。

    <!--
    	Note: Static (i.e., not template-generated) href and id
    	attributes start with "pkg-" to make it impossible for
    	them to conflict with generated attributes (some of which
    	correspond to Go identifiers).
    -->
    

    このコメントは、将来のメンテナンス担当者やコードレビューアに対して、なぜこのようなプレフィックスが導入されたのか、その背景にある設計思想を明確に伝えます。これは、コードの可読性と保守性を高める上で非常に重要です。

  3. 「Other packages」リンクの追加: short-nav(短いナビゲーションメニュー)内に、$.PList(他のパッケージのリストが存在する場合)の条件付きで「Other packages」へのリンクが追加されました。このリンクのidも同様にpkg-other-packagesとプレフィックスされています。これにより、ユーザーは現在のパッケージに関連する他のパッケージに簡単にアクセスできるようになります。

これらの変更により、godocが生成するHTMLドキュメントは、IE9のようなブラウザでもid属性の競合による問題を回避し、より堅牢で互換性の高いものとなります。

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

diff --git a/lib/godoc/package.html b/lib/godoc/package.html
index e037072211..ab9e521c34 100644
--- a/lib/godoc/package.html
+++ b/lib/godoc/package.html
@@ -3,6 +3,12 @@
  	Use of this source code is governed by a BSD-style
  	license that can be found in the LICENSE file.\n -->
 +<!--
++	Note: Static (i.e., not template-generated) href and id
++	attributes start with "pkg-" to make it impossible for
++	them to conflict with generated attributes (some of which
++	correspond to Go identifiers).\n+-->
  {{with .PDoc}}\n  	{{if $.IsPkg}}\n  	\t<div id=\"short-nav\">\n@@ -10,18 +16,21 @@\n  	\t\t<dd><code>import \"{{html .ImportPath}}\"</code></dd>\n  	\t\t</dl>\n  	\t\t<dl>\n-\t\t\t<dd><a href=\"#overview\" class=\"overviewLink\">Overview</a></dd>\n-\t\t\t<dd><a href=\"#index\">Index</a></dd>\n+\t\t\t<dd><a href=\"#pkg-overview\" class=\"overviewLink\">Overview</a></dd>\n+\t\t\t<dd><a href=\"#pkg-index\">Index</a></dd>\n  	\t\t{{if $.Examples}}\n-\t\t\t\t<dd><a href=\"#examples\">Examples</a></dd>\n+\t\t\t\t<dd><a href=\"#pkg-examples\">Examples</a></dd>\n+\t\t\t{{end}}\n+\t\t\t{{if $.PList}}\n+\t\t\t\t<dd><a href=\"#pkg-other-packages\">Other packages</a></dd>\n  	\t\t{{end}}\n  	\t\t{{if $.Dirs}}\n-\t\t\t\t<dd><a href=\"#subdirectories\">Subdirectories</a></dd>\n+\t\t\t\t<dd><a href=\"#pkg-subdirectories\">Subdirectories</a></dd>\n  	\t\t{{end}}\n  	\t\t</dl>\n  	\t</div>\n  	\t<!-- The package\'s Name is printed as title by the top-level template -->\n-\t\t<div id=\"overview\" class=\"toggleVisible\">\n+\t\t<div id=\"pkg-overview\" class=\"toggleVisible\">\n  	\t\t<div class=\"collapsed\">\n  	\t\t\t<h2 class=\"toggleButton\" title=\"Click to show Overview section\">Overview ▹</h2>\n  	\t\t</div>\n@@ -32,15 +41,15 @@\n  	\t</div>\n  	\t{{example_html \"\" $.Examples $.FSet}}\n  	\n-\t\t<h2 id=\"index\">Index</h2>\n+\t\t<h2 id=\"pkg-index\">Index</h2>\n  	\t<!-- Table of contents for API; must be named manual-nav to turn off auto nav. -->\n  	\t<div id=\"manual-nav\">\n  	\t\t<dl>\n  	\t\t{{if .Consts}}\n-\t\t\t\t<dd><a href=\"#constants\">Constants</a></dd>\n+\t\t\t\t<dd><a href=\"#pkg-constants\">Constants</a></dd>\n  	\t\t{{end}}\n  	\t\t{{if .Vars}}\n-\t\t\t\t<dd><a href=\"#variables\">Variables</a></dd>\n+\t\t\t\t<dd><a href=\"#pkg-variables\">Variables</a></dd>\n  	\t\t{{end}}\n  	\t\t{{range .Funcs}}\n  	\t\t\t{{$name_html := html .Name}}\n@@ -59,12 +68,12 @@\n  	\t\t\t{{end}}\n  	\t\t{{end}}\n  	\t\t{{if .Bugs}}\n-\t\t\t\t<dd><a href=\"#bugs\">Bugs</a></dd>\n+\t\t\t\t<dd><a href=\"#pkg-bugs\">Bugs</a></dd>\n  	\t\t{{end}}\n  	\t</dl>\n  \n  	\t{{if $.Examples}}\n-\t\t\t<h4 id=\"examples\">Examples</h4>\n+\t\t\t<h4 id=\"pkg-examples\">Examples</h4>\n  	\t\t<dl>\n  	\t\t{{range $.Examples}}\n  	\t\t<dd><a class=\"exampleLink\" href=\"#example_{{.Name}}\">{{example_name .Name}}</a></dd>\n@@ -84,14 +93,14 @@\n  	\t{{end}}\n  	\n  	\t{{with .Consts}}\n-\t\t\t<h2 id=\"constants\">Constants</h2>\n+\t\t\t<h2 id=\"pkg-constants\">Constants</h2>\n  	\t\t{{range .}}\n  	\t\t\t<pre>{{node_html .Decl $.FSet}}</pre>\n  	\t\t\t{{comment_html .Doc}}\n  	\t\t{{end}}\n  	\t{{end}}\n  	\t{{with .Vars}}\n-\t\t\t<h2 id=\"variables\">Variables</h2>\n+\t\t\t<h2 id=\"pkg-variables\">Variables</h2>\n  	\t\t{{range .}}\n  	\t\t\t<pre>{{node_html .Decl $.FSet}}</pre>\n  	\t\t\t{{comment_html .Doc}}\n@@ 147,7 +156,7 @@\n  	{{end}}\n  \n  	{{with .Bugs}}\n-\t\t<h2 id=\"bugs\">Bugs</h2>\n+\t\t<h2 id=\"pkg-bugs\">Bugs</h2>\n  	\t{{range .}}\n  	\t{{comment_html .}}\n  	\t{{end}}\n@@ 159,7 +168,7 @@\n  {{end}}\n  \n  {{with .PList}}\n-\t<h2>Other packages</h2>\n+\t<h2 id=\"pkg-other-packages\">Other packages</h2>\n  \t<p>\n  \t{{/* PList entries are strings - no need for FSet */}}\n  \t{{range .}}\n@@ 171,7 +180,7 @@\n  {{with .Dirs}}\n  	{{/* DirList entries are numbers and strings - no need for FSet */}}\n  	{{if $.PDoc}}\n-\t\t<h2 id=\"subdirectories\">Subdirectories</h2>\n+\t\t<h2 id=\"pkg-subdirectories\">Subdirectories</h2>\n  	{{else}}\n  	\t<div class=\"pkgGopher\">\n  	\t\t<img class=\"gopher\" src=\"/doc/gopher/pkg.png\"/>\n```

## コアとなるコードの解説

上記の差分は、`lib/godoc/package.html`テンプレートファイルに対する変更を示しています。

1.  **HTMLコメントの追加 (行 4-9)**:
    ```html
    +<!--
    +	Note: Static (i.e., not template-generated) href and id
    +	attributes start with "pkg-" to make it impossible for
    +	them to conflict with generated attributes (some of which
    +	correspond to Go identifiers).
    +-->
    ```
    これは、このファイルで行われた変更の意図を説明する新しいHTMLコメントです。静的に定義された`href`および`id`属性が`pkg-`で始まる理由を明確に述べており、Goの識別子から生成される属性との競合を避けるためであることが示されています。

2.  **ナビゲーションリンクの`id`と`href`の変更 (行 13-24)**:
    ```diff
    -			<dd><a href="#overview" class="overviewLink">Overview</a></dd>
    -			<dd><a href="#index">Index</a></dd>
    +			<dd><a href="#pkg-overview" class="overviewLink">Overview</a></dd>
    +			<dd><a href="#pkg-index">Index</a></dd>
     	\t\t{{if $.Examples}}
    -			<dd><a href="#examples">Examples</a></dd>
    +			<dd><a href="#pkg-examples">Examples</a></dd>
    +			{{end}}
    +			{{if $.PList}}
    +				<dd><a href="#pkg-other-packages">Other packages</a></dd>
     	\t\t{{end}}
     	\t\t{{if $.Dirs}}
    -			<dd><a href="#subdirectories">Subdirectories</a></dd>
    +			<dd><a href="#pkg-subdirectories">Subdirectories</a></dd>
    ```
    `short-nav`セクション内の各ナビゲーションリンク(Overview, Index, Examples, Subdirectories)の`href`属性が、対応する`id`属性に合わせて`#pkg-`プレフィックスを持つように変更されています。
    また、`{{if $.PList}}`ブロックが追加され、`PList`(他のパッケージのリスト)が存在する場合に「Other packages」へのリンクが動的に表示されるようになりました。このリンクの`href`も`#pkg-other-packages`となっています。

3.  **セクション`id`の変更 (行 27, 35, 44, 47, 56, 65, 74)**:
    ```diff
    -		<div id="overview" class="toggleVisible">
    +		<div id="pkg-overview" class="toggleVisible">
     ...
    -		<h2 id="index">Index</h2>
    +		<h2 id="pkg-index">Index</h2>
     ...
    -			<dd><a href="#constants">Constants</a></dd>
    +			<dd><a href="#pkg-constants">Constants</a></dd>
     	\t\t{{end}}
     	\t\t{{if .Vars}}
    -			<dd><a href="#variables">Variables</a></dd>
    +			<dd><a href="#pkg-variables">Variables</a></dd>
     ...
    -			<dd><a href="#bugs">Bugs</a></dd>
    +			<dd><a href="#pkg-bugs">Bugs</a></dd>
     ...
    -		<h4 id="examples">Examples</h4>
    +		<h4 id="pkg-examples">Examples</h4>
     ...
    -		<h2 id="constants">Constants</h2>
    +		<h2 id="pkg-constants">Constants</h2>
     ...
    -		<h2 id="variables">Variables</h2>
    +		<h2 id="pkg-variables">Variables</h2>
     ...
    -		<h2 id="bugs">Bugs">Bugs</h2>
    +		<h2 id="pkg-bugs">Bugs</h2>
     ...
    -	<h2>Other packages</h2>
    +	<h2 id="pkg-other-packages">Other packages</h2>
     ...
    -		<h2 id="subdirectories">Subdirectories</h2>
    +		<h2 id="pkg-subdirectories">Subdirectories</h2>
    ```
    `overview`, `index`, `constants`, `variables`, `bugs`, `examples`, `other-packages`, `subdirectories`といった主要なセクションの`id`属性も、すべて`pkg-`プレフィックスを持つように変更されています。これにより、これらのセクションへのページ内リンクが正しく機能し、動的に生成される可能性のある`id`との競合が回避されます。

これらの変更は、`godoc`が生成するHTMLドキュメントの堅牢性とクロスブラウザ互換性を向上させるための重要なステップです。

## 関連リンク

*   **Go CL (Code Review)**: [https://golang.org/cl/6449105](https://golang.org/cl/6449105)
*   **Go Issue**: [https://github.com/golang/go/issues/3851](https://github.com/golang/go/issues/3851)

## 参考にした情報源リンク

*   HTML `id` 属性の仕様: [https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/id](https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/id)
*   `godoc`について: [https://pkg.go.dev/cmd/godoc](https://pkg.go.dev/cmd/godoc) (Goの公式ドキュメント)
*   Internet Explorer 9 (IE9) の互換性情報 (一般的なウェブ開発の知識として)