calendar_viewer.inc.php と comment.inc.php の併用で XHTML 1.1 invalid

メッセージ

calendar_viewer で表示した複数の記事中に comment プラグインが使われていると、フォーム中の "msg" および "name" に設定された id が重複してしまい、XHTML 1.1 invalid になってしまう。

関連

問題点

calendar_viewer.inc.php 160行付近

	// $limit_page の件数までインクルード
	$tmp = max($limit_base, 0); // Skip minus
	while ($tmp < $limit_page) {
		if (! isset($pagelist[$tmp])) break;

		$page = $pagelist[$tmp];
		$get['page'] = $post['page'] = $vars['page'] = $page;

$vars['page'] にインクルードする記事名をセットしている。

comment.inc.php 90行付近

function plugin_comment_convert()
{
	global $vars, $digest, $_btn_comment, $_btn_name, $_msg_comment;
	static $numbers = array();
	static $comment_cols = PLUGIN_COMMENT_SIZE_MSG;

	if (PKWK_READONLY) return ''; // Show nothing

	if (! isset($numbers[$vars['page']])) $numbers[$vars['page']] = 0;
	$comment_no = $numbers[$vars['page']]++;

$vars['page'] をキーにして$comment_noをセットしている。
$comment_no はその後 id の生成に利用している。

comment.inc.php の挙動は、同一ページ内に複数の #comment があっても id が被らないようにしている。
calendar_viewer を使用すると、親ページ内に複数の子ページが存在するイメージとなり、子ページ内での整合性は保たれるものの、子ページ間での競合が避けられない。

問題点の本質

label要素(に限らず、(x)htmlすべて)におけるid属性は、(x)html文書内で一意で無ければならない。
calendar_viewer.inc.phpは1つの(x)html文書内に複数のページ(wiki)を表示しようとする。
comment.inc.phpにおける$comment_no変数は、(x)html文書内での表示位置/順序に係わらず、ページ(wiki)内での出現順で普遍の一意の値で無ければならない。
管理の基準となる対象が違う二つの要素を一つの変数で管理しようとしているところに問題がある。

改修案1

input要素中の id は、label要素との紐付けのためだけに使われており、プログラム的には何ら意味の無い値である。
commentプラグインにて、idの生成にはページ名に拠らず出現回数のみを拠り所にする変数を新設して、それを使うように修正することでこの問題は解決できる。

comment.inc.php

function plugin_comment_convert()
 {
 	global $vars, $digest, $_btn_comment, $_btn_name, $_msg_comment;
 	static $numbers = array();
+	static $commentnums = 0;
 	static $comment_cols = PLUGIN_COMMENT_SIZE_MSG;
 
 	if (PKWK_READONLY) return ''; // Show nothing
 
 	if (! isset($numbers[$vars['page']])) $numbers[$vars['page']] = 0;
 	$comment_no = $numbers[$vars['page']]++;
+	$commentnums++;
 
 	$options = func_num_args() ? func_get_args() : array();
 	if (in_array('noname', $options)) {
-		$nametags = '<label for="_p_comment_comment_' . $comment_no . '">' .
+		$nametags = '<label for="_p_comment_comment_' . $commentnums . '">' .
 			$_msg_comment . '</label>';
 	} else {
-		$nametags = '<label for="_p_comment_name_' . $comment_no . '">' .
+		$nametags = '<label for="_p_comment_name_' . $commentnums . '">' .
 			$_btn_name . '</label>' .
 			'<input type="text" name="name" id="_p_comment_name_' .
-			$comment_no .  '" size="' . PLUGIN_COMMENT_SIZE_NAME .
+			$commentnums .  '" size="' . PLUGIN_COMMENT_SIZE_NAME .
 			'" />' . "\n";
 	}
 (中略)
   <input type="hidden" name="digest" value="$digest" />
   $nametags
-  <input type="text"   name="msg" id="_p_comment_comment_{$comment_no}" size="$comment_cols" />
+  <input type="text"   name="msg" id="_p_comment_comment_{$commentnums}" size="$comment_cols" />
   <input type="submit" name="comment" value="$_btn_comment" />

改修案2

そもそもlabel要素が不要ではないか。
label要素は、input要素の type="radio" や type="checkbox" 等でユーザビリティの向上を図る目的で使われるのだが、type="text" ではそれほどユーザビリティの向上には貢献しない。
そこで、label要素を廃止して、id 自体を不要にしてしまうことで問題の解決を図る。

comment.inc.php

function plugin_comment_convert()
 {
 	global $vars, $digest, $_btn_comment, $_btn_name, $_msg_comment;
 	static $numbers = array();
 	static $comment_cols = PLUGIN_COMMENT_SIZE_MSG;
 
 	if (PKWK_READONLY) return ''; // Show nothing
 
 	if (! isset($numbers[$vars['page']])) $numbers[$vars['page']] = 0;
 	$comment_no = $numbers[$vars['page']]++;
 
 	$options = func_num_args() ? func_get_args() : array();
 	if (in_array('noname', $options)) {
-		$nametags = '<label for="_p_comment_comment_' . $comment_no . '">' .
-			$_msg_comment . '</label>';
+		$nametags = $_msg_comment;
 	} else {
-		$nametags = '<label for="_p_comment_name_' . $comment_no . '">' .
-			$_btn_name . '</label>' .
-			'<input type="text" name="name" id="_p_comment_name_' .
-			$comment_no .  '" size="' . PLUGIN_COMMENT_SIZE_NAME .
+		$nametags = $_btn_name . '<input type="text" name="name" size="' . PLUGIN_COMMENT_SIZE_NAME .
 			'" />' . "\n";
 	}
 (中略)
   <input type="hidden" name="digest" value="$digest" />
   $nametags
-  <input type="text"   name="msg" id="_p_comment_comment_{$comment_no}" size="$comment_cols" />
+  <input type="text"   name="msg" size="$comment_cols" />
   <input type="submit" name="comment" value="$_btn_comment" />

類似問題

PukiWikiで label 要素を使用しているソースは、comment.inc.php を除いて14個ある。

以下未調査


コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-12-28 (日) 17:48:02
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.221 sec.

SourceForge