Issue #1272870 by mvc, mgifford, xjm, Drupali, Everett Zufelt: Fixed No semantics for nested comments / bad for screen-readers.
parent
95ce944803
commit
6c7fa21356
|
@ -1657,6 +1657,30 @@ function template_preprocess_comment(&$variables) {
|
|||
$variables['permalink'] = l(t('Permalink'), $uri['path'], $uri['options']);
|
||||
$variables['submitted'] = t('Submitted by !username on !datetime', array('!username' => $variables['author'], '!datetime' => $variables['created']));
|
||||
|
||||
if ($comment->pid > 0) {
|
||||
// Fetch and store the parent comment information for use in templates.
|
||||
$comment_parent = comment_load($comment->pid);
|
||||
$variables['parent_comment'] = $comment_parent;
|
||||
$variables['parent_author'] = theme('username', array('account' => $comment_parent));
|
||||
$variables['parent_created'] = format_date($comment_parent->created);
|
||||
$variables['parent_changed'] = format_date($comment_parent->changed);
|
||||
$uri_parent = $comment_parent->uri();
|
||||
$uri_parent['options'] += array('attributes' => array('class' => 'permalink', 'rel' => 'bookmark'));
|
||||
$variables['parent_title'] = l($comment_parent->subject, $uri_parent['path'], $uri_parent['options']);
|
||||
$variables['parent_permalink'] = l(t('Parent permalink'), $uri_parent['path'], $uri_parent['options']);
|
||||
$variables['parent'] = t('In reply to !parent_title by !parent_username',
|
||||
array('!parent_username' => $variables['parent_author'], '!parent_title' => $variables['parent_title']));
|
||||
}
|
||||
else {
|
||||
$variables['parent_comment'] = '';
|
||||
$variables['parent_author'] = '';
|
||||
$variables['parent_created'] = '';
|
||||
$variables['parent_changed'] = '';
|
||||
$variables['parent_title'] = '';
|
||||
$variables['parent_permalink'] = '';
|
||||
$variables['parent'] = '';
|
||||
}
|
||||
|
||||
// Preprocess fields.
|
||||
field_attach_preprocess('comment', $comment, $variables['elements'], $variables);
|
||||
|
||||
|
|
|
@ -40,64 +40,138 @@ class CommentThreadingTest extends CommentTestBase {
|
|||
$this->drupalLogin($this->web_user);
|
||||
$subject_text = $this->randomName();
|
||||
$comment_text = $this->randomName();
|
||||
$comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
|
||||
$comment_loaded = comment_load($comment->id);
|
||||
$this->assertTrue($this->commentExists($comment), 'Comment #1. Comment found.');
|
||||
$this->assertEqual($comment_loaded->thread, '01/');
|
||||
$comment1 = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment1_loaded = comment_load($comment1->id);
|
||||
$this->assertTrue($this->commentExists($comment1), 'Comment #1. Comment found.');
|
||||
$this->assertEqual($comment1_loaded->thread, '01/');
|
||||
// Confirm that there is no reference to a parent comment.
|
||||
$this->assertNoParentLink($comment1->id);
|
||||
|
||||
// Reply to comment #1 creating comment #2.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($reply, TRUE), 'Comment #2. Reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '01.00/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment1->id);
|
||||
$comment2 = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment2_loaded = comment_load($comment2->id);
|
||||
$this->assertTrue($this->commentExists($comment2, TRUE), 'Comment #2. Reply found.');
|
||||
$this->assertEqual($comment2_loaded->thread, '01.00/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment2->id, $comment1->id);
|
||||
|
||||
// Reply to comment #2 creating comment #3.
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $reply->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($reply, TRUE), 'Comment #3. Second reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '01.00.00/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment2->id);
|
||||
$comment3 = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment3_loaded = comment_load($comment3->id);
|
||||
$this->assertTrue($this->commentExists($comment3, TRUE), 'Comment #3. Second reply found.');
|
||||
$this->assertEqual($comment3_loaded->thread, '01.00.00/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment3->id, $comment2->id);
|
||||
|
||||
// Reply to comment #1 creating comment #4.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($comment), 'Comment #4. Third reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '01.01/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment1->id);
|
||||
$comment4 = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment4_loaded = comment_load($comment4->id);
|
||||
$this->assertTrue($this->commentExists($comment4), 'Comment #4. Third reply found.');
|
||||
$this->assertEqual($comment4_loaded->thread, '01.01/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment4->id, $comment1->id);
|
||||
|
||||
// Post comment #2 overall comment #5.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$subject_text = $this->randomName();
|
||||
$comment_text = $this->randomName();
|
||||
$comment = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
|
||||
$comment_loaded = comment_load($comment->id);
|
||||
$this->assertTrue($this->commentExists($comment), 'Comment #5. Second comment found.');
|
||||
$this->assertEqual($comment_loaded->thread, '02/');
|
||||
$comment5 = $this->postComment($this->node, $comment_text, $subject_text, TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment5_loaded = comment_load($comment5->id);
|
||||
$this->assertTrue($this->commentExists($comment5), 'Comment #5. Second comment found.');
|
||||
$this->assertEqual($comment5_loaded->thread, '02/');
|
||||
// Confirm that there is no link to a parent comment.
|
||||
$this->assertNoParentLink($comment5->id);
|
||||
|
||||
// Reply to comment #5 creating comment #6.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($reply, TRUE), 'Comment #6. Reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '02.00/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment5->id);
|
||||
$comment6 = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment6_loaded = comment_load($comment6->id);
|
||||
$this->assertTrue($this->commentExists($comment6, TRUE), 'Comment #6. Reply found.');
|
||||
$this->assertEqual($comment6_loaded->thread, '02.00/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment6->id, $comment5->id);
|
||||
|
||||
// Reply to comment #6 creating comment #7.
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $reply->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($reply, TRUE), 'Comment #7. Second reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '02.00.00/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment6->id);
|
||||
$comment7 = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment7_loaded = comment_load($comment7->id);
|
||||
$this->assertTrue($this->commentExists($comment7, TRUE), 'Comment #7. Second reply found.');
|
||||
$this->assertEqual($comment7_loaded->thread, '02.00.00/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment7->id, $comment6->id);
|
||||
|
||||
// Reply to comment #5 creating comment #8.
|
||||
$this->drupalLogin($this->web_user);
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id);
|
||||
$reply = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
$reply_loaded = comment_load($reply->id);
|
||||
$this->assertTrue($this->commentExists($comment), 'Comment #8. Third reply found.');
|
||||
$this->assertEqual($reply_loaded->thread, '02.01/');
|
||||
$this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment5->id);
|
||||
$comment8 = $this->postComment(NULL, $this->randomName(), '', TRUE);
|
||||
// Confirm that the comment was created and has the correct threading.
|
||||
$comment8_loaded = comment_load($comment8->id);
|
||||
$this->assertTrue($this->commentExists($comment8), 'Comment #8. Third reply found.');
|
||||
$this->assertEqual($comment8_loaded->thread, '02.01/');
|
||||
// Confirm that there is a link to the parent comment.
|
||||
$this->assertParentLink($comment8->id, $comment5->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the link to the specified parent comment is present.
|
||||
*
|
||||
* @parm int $cid
|
||||
* The comment ID to check.
|
||||
* @param int $pid
|
||||
* The expected parent comment ID.
|
||||
*/
|
||||
protected function assertParentLink($cid, $pid) {
|
||||
// This pattern matches a markup structure like:
|
||||
// <a id="comment-2"></a>
|
||||
// <article>
|
||||
// <p class="parent">
|
||||
// <a href="...comment-1"></a>
|
||||
// </p>
|
||||
// </article>
|
||||
$pattern = "//a[@id='comment-$cid']/following-sibling::article//p[contains(@class, 'parent')]//a[contains(@href, 'comment-$pid')]";
|
||||
|
||||
$this->assertFieldByXpath($pattern, NULL, format_string(
|
||||
'Comment %cid has a link to parent %pid.',
|
||||
array(
|
||||
'%cid' => $cid,
|
||||
'%pid' => $pid,
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified comment does not have a link to a parent.
|
||||
*
|
||||
* @parm int $cid
|
||||
* The comment ID to check.
|
||||
*/
|
||||
protected function assertNoParentLink($cid) {
|
||||
// This pattern matches a markup structure like:
|
||||
// <a id="comment-2"></a>
|
||||
// <article>
|
||||
// <p class="parent"></p>
|
||||
// </article>
|
||||
|
||||
$pattern = "//a[@id='comment-$cid']/following-sibling::article//p[contains(@class, 'parent')]";
|
||||
$this->assertNoFieldByXpath($pattern, NULL, format_string(
|
||||
'Comment %cid does not have a link to a parent.',
|
||||
array(
|
||||
'%cid' => $cid,
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,20 @@
|
|||
* modules, intended to be displayed after the main title tag that appears in
|
||||
* the template.
|
||||
*
|
||||
* These variables are provided to give context about the parent comment (if
|
||||
* any):
|
||||
* - $comment_parent: Full parent comment object (if any).
|
||||
* - $parent_author: Equivalent to $author for the parent comment.
|
||||
* - $parent_created: Equivalent to $created for the parent comment.
|
||||
* - $parent_changed: Equivalent to $changed for the parent comment.
|
||||
* - $parent_title: Equivalent to $title for the parent comment.
|
||||
* - $parent_permalink: Equivalent to $permalink for the parent comment.
|
||||
* - $parent: A text string of parent comment submission information created
|
||||
* from $parent_author and $parent_created during
|
||||
* template_preprocess_comment(). This information is presented to help
|
||||
* screen readers follow lengthy discussion threads. You can hide this from
|
||||
* sighted users using the class element-invisible.
|
||||
*
|
||||
* These two variables are provided for context:
|
||||
* - $comment: Full comment object.
|
||||
* - $node: Node entity the comments are attached to.
|
||||
|
@ -67,6 +81,14 @@
|
|||
<footer>
|
||||
<?php print $user_picture; ?>
|
||||
<p class="submitted"><?php print $submitted; ?></p>
|
||||
<?php
|
||||
// Indicate the semantic relationship between parent and child comments
|
||||
// for accessibility. The list is difficult to navigate in a screen
|
||||
// reader without this information.
|
||||
if ($parent):
|
||||
?>
|
||||
<p class="parent element-invisible"><?php print $parent; ?></p>
|
||||
<?php endif; ?>
|
||||
<?php print $permalink; ?>
|
||||
</footer>
|
||||
|
||||
|
|
Loading…
Reference in New Issue