mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-24 00:13:36 +00:00
Add reply links at the end of a line, even if the signature is in the middle
Previously they were added at the end of the text node containing the timestamp, which was usually the end of the line, but not always. And also fix the same problem for inserting the actual replies (or reply widgets). This replaces an undocumented hack that prevented our own reply links from triggering this bug (without it, the reply widget would be inserted before the reply link rather than after). While we're here, remove unintentional spacing that appeared before some reply links, caused by trailing whitespace in text nodes. Add tests for all of the above. Bug: T245695 Change-Id: I354b63e2446bb996176a2e3d76abf944127f307e
This commit is contained in:
parent
711d5c4371
commit
606d6b34ec
|
@ -176,10 +176,12 @@
|
|||
"templates": [
|
||||
"cases/en-big-oldparser/en-big-oldparser.html",
|
||||
"cases/en-big-oldparser/en-big-oldparser-modified.html",
|
||||
"cases/en-big-oldparser/en-big-oldparser-reply.html",
|
||||
"cases/en-big-parsoid/en-big-parsoid.html",
|
||||
"cases/en-big-parsoid/en-big-parsoid-modified.html",
|
||||
"cases/pl-big-oldparser/pl-big-oldparser.html",
|
||||
"cases/pl-big-oldparser/pl-big-oldparser-modified.html",
|
||||
"cases/pl-big-oldparser/pl-big-oldparser-reply.html",
|
||||
"cases/pl-big-parsoid/pl-big-parsoid.html",
|
||||
"cases/pl-big-parsoid/pl-big-parsoid-modified.html",
|
||||
"cases/no-heading/no-heading.html",
|
||||
|
@ -188,7 +190,10 @@
|
|||
"cases/split-list/split-list.html",
|
||||
"cases/split-list/split-list-modified.html",
|
||||
"cases/split-list2/split-list2.html",
|
||||
"cases/split-list2/split-list2-modified.html"
|
||||
"cases/split-list2/split-list2-modified.html",
|
||||
"cases/signatures-funny/signatures-funny.html",
|
||||
"cases/signatures-funny/signatures-funny-modified.html",
|
||||
"cases/signatures-funny/signatures-funny-reply.html"
|
||||
],
|
||||
"dependencies": [
|
||||
"ext.discussionTools.modifier",
|
||||
|
|
|
@ -13,8 +13,7 @@ var
|
|||
mw.loader.using( 'ext.discussionTools.ReplyWidgetPlain' );
|
||||
|
||||
function setupComment( comment ) {
|
||||
var $replyLink, widgetPromise, newListItem,
|
||||
$tsNode = $( comment.range.endContainer );
|
||||
var $replyLink, widgetPromise, newListItem;
|
||||
|
||||
// Is it possible to have a heading nested in a thread?
|
||||
if ( comment.type !== 'comment' ) {
|
||||
|
@ -91,7 +90,7 @@ function setupComment( comment ) {
|
|||
} );
|
||||
} );
|
||||
|
||||
$tsNode.after( $replyLink );
|
||||
modifier.addReplyLink( comment, $replyLink[ 0 ] );
|
||||
}
|
||||
|
||||
function traverseNode( parent ) {
|
||||
|
|
|
@ -37,6 +37,41 @@ function whitespaceParsoidHack( listItem ) {
|
|||
listItem.setAttribute( 'data-parsoid', '{}' );
|
||||
}
|
||||
|
||||
function isTalkpageListNode( node ) {
|
||||
var tag = node.tagName ? node.tagName.toLowerCase() : '';
|
||||
return tag === 'dl' || tag === 'ul';
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a comment and a reply link, add the reply link to its document's DOM tree, at the end of
|
||||
* the comment.
|
||||
*
|
||||
* @param {Object} comment Comment data returned by parser#groupThreads
|
||||
* @param {HTMLElement} linkNode Reply link
|
||||
*/
|
||||
function addReplyLink( comment, linkNode ) {
|
||||
var target = comment.range.endContainer;
|
||||
|
||||
// Skip to the end of the "paragraph".
|
||||
// Actually doing this by paragraph would require us to know how the text is laid out, and
|
||||
// would be more difficult and probably slower. Instead skip over anything that isn't a list
|
||||
// node, which should have the same effect on discussion pages.
|
||||
while ( target.nextSibling && !isTalkpageListNode( target.nextSibling ) ) {
|
||||
target = target.nextSibling;
|
||||
}
|
||||
|
||||
// Insert the link before trailing whitespace.
|
||||
// In the MediaWiki parser output, <ul>/<dl> nodes are preceded by a newline. Normally it isn't
|
||||
// visible on the page. But if we insert an inline element (the reply link) after it, it becomes
|
||||
// meaningful and gets rendered, which results in additional spacing before some reply links.
|
||||
// Split the text node, so that we can insert the link before the trailing whitespace.
|
||||
if ( target.nodeType === Node.TEXT_NODE ) {
|
||||
target.splitText( target.textContent.match( /\s*$/ ).index );
|
||||
}
|
||||
|
||||
target.parentNode.insertBefore( linkNode, target.nextSibling );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a comment, add a list item to its document's DOM tree, inside of which a reply to said
|
||||
* comment can be added.
|
||||
|
@ -69,12 +104,16 @@ function addListItem( comment ) {
|
|||
desiredLevel = comment.level + 1;
|
||||
currLevel = currComment.level;
|
||||
target = currComment.range.endContainer;
|
||||
// HACK
|
||||
if ( target.nextSibling && target.nextSibling.classList.contains( 'dt-init-replylink' ) ) {
|
||||
|
||||
// Skip to the end of the "paragraph".
|
||||
// Actually doing this by paragraph would require us to know how the text is laid out, and
|
||||
// would be more difficult and probably slower. Instead skip over anything that isn't a list
|
||||
// node, which should have the same effect on discussion pages.
|
||||
while ( target.nextSibling && !isTalkpageListNode( target.nextSibling ) ) {
|
||||
target = target.nextSibling;
|
||||
}
|
||||
|
||||
// endContainer is probably a text node, and it may also be wrapped in some formatting.
|
||||
// target is a text node or an inline element at the end of a "paragraph" (not necessarily paragraph node).
|
||||
// First, we need to find a block-level parent that we can mess with.
|
||||
// If we can't find a surrounding list item or paragraph (e.g. maybe we're inside a table cell
|
||||
// or something), take the parent node and hope for the best.
|
||||
|
@ -214,6 +253,7 @@ function createWikitextNode( wt ) {
|
|||
|
||||
module.exports = {
|
||||
closest: closest,
|
||||
addReplyLink: addReplyLink,
|
||||
addListItem: addListItem,
|
||||
removeListItem: removeListItem,
|
||||
addSiblingListItem: addSiblingListItem,
|
||||
|
|
2929
tests/qunit/cases/en-big-oldparser/en-big-oldparser-reply.html
Normal file
2929
tests/qunit/cases/en-big-oldparser/en-big-oldparser-reply.html
Normal file
File diff suppressed because one or more lines are too long
421
tests/qunit/cases/pl-big-oldparser/pl-big-oldparser-reply.html
Normal file
421
tests/qunit/cases/pl-big-oldparser/pl-big-oldparser-reply.html
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,10 @@
|
|||
<h2><span class="mw-headline" id="multi_signatures">multi signatures</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Talk:Scratch&action=edit&section=5" title="Edit section: multi signatures">edit source</a><span class="mw-editsection-bracket">]</span></span></h2>
|
||||
<p>aaa <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)
|
||||
</p>
|
||||
<ul><li>bbb <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)
|
||||
<ul><li>ccc <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)<ul><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:31:00.000Z|2</li></ul></li><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:31:00.000Z|1</li></ul></li><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:31:00.000Z|0</li></ul>
|
||||
<p>ddd <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)
|
||||
</p>
|
||||
<ul><li>eee <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)<ul><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:31:00.000Z|4</li></ul></li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) also!<ul><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:35:00.000Z|0</li></ul></li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) and <i>also</i>!<ul><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:35:00.000Z|1</li></ul></li><li data-parsoid="{}">Reply to Matma Rex|2020-01-25T08:31:00.000Z|3</li></ul>
|
|
@ -0,0 +1,10 @@
|
|||
<h2><span class="mw-headline" id="multi_signatures">multi signatures</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Talk:Scratch&action=edit&section=5" title="Edit section: multi signatures">edit source</a><span class="mw-editsection-bracket">]</span></span></h2>
|
||||
<p>aaa <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)<a href="#">Reply</a>
|
||||
</p>
|
||||
<ul><li>bbb <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)<a href="#">Reply</a>
|
||||
<ul><li>ccc <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)<a href="#">Reply</a></li></ul></li></ul>
|
||||
<p>ddd <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)<a href="#">Reply</a>
|
||||
</p>
|
||||
<ul><li>eee <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)<a href="#">Reply</a></li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) also!<a href="#">Reply</a></li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) and <i>also</i>!<a href="#">Reply</a></li></ul>
|
10
tests/qunit/cases/signatures-funny/signatures-funny.html
Normal file
10
tests/qunit/cases/signatures-funny/signatures-funny.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<h2><span class="mw-headline" id="multi_signatures">multi signatures</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Talk:Scratch&action=edit&section=5" title="Edit section: multi signatures">edit source</a><span class="mw-editsection-bracket">]</span></span></h2>
|
||||
<p>aaa <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)
|
||||
</p>
|
||||
<ul><li>bbb <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)
|
||||
<ul><li>ccc <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)</li></ul></li></ul>
|
||||
<p>ddd <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC)
|
||||
</p>
|
||||
<ul><li>eee <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:31, 25 January 2020 (UTC) amended! <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:32, 25 January 2020 (UTC)</li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) also!</li>
|
||||
<li>fff <b><a href="/wiki/User:Matma_Rex" title="User:Matma Rex">Matma Rex</a> | <a href="/wiki/User_talk:Matma_Rex" title="User talk:Matma Rex">talk</a></b> 08:35, 25 January 2020 (UTC) and <i>also</i>!</li></ul>
|
|
@ -52,6 +52,13 @@ QUnit.test( '#addListItem/#removeListItem', function ( assert ) {
|
|||
expected: mw.template.get( 'test.DiscussionTools', 'cases/split-list2/split-list2-modified.html' ).render(),
|
||||
config: require( './data/enwiki-config.json' ),
|
||||
data: require( './data/enwiki-data.json' )
|
||||
},
|
||||
{
|
||||
name: 'Signatures in funny places',
|
||||
dom: mw.template.get( 'test.DiscussionTools', 'cases/signatures-funny/signatures-funny.html' ).render(),
|
||||
expected: mw.template.get( 'test.DiscussionTools', 'cases/signatures-funny/signatures-funny-modified.html' ).render(),
|
||||
config: require( './data/enwiki-config.json' ),
|
||||
data: require( './data/enwiki-data.json' )
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -107,3 +114,68 @@ QUnit.test( '#addListItem/#removeListItem', function ( assert ) {
|
|||
);
|
||||
}
|
||||
} );
|
||||
|
||||
QUnit.test( '#addReplyLink', function ( assert ) {
|
||||
var i, j, cases, actualHtml, expectedHtml, comments, linkNode, fixture;
|
||||
|
||||
cases = [
|
||||
{
|
||||
name: 'plwiki oldparser',
|
||||
dom: mw.template.get( 'test.DiscussionTools', 'cases/pl-big-oldparser/pl-big-oldparser.html' ).render(),
|
||||
expected: mw.template.get( 'test.DiscussionTools', 'cases/pl-big-oldparser/pl-big-oldparser-reply.html' ).render(),
|
||||
config: require( './data/plwiki-config.json' ),
|
||||
data: require( './data/plwiki-data.json' )
|
||||
},
|
||||
{
|
||||
name: 'enwiki oldparser',
|
||||
dom: mw.template.get( 'test.DiscussionTools', 'cases/en-big-oldparser/en-big-oldparser.html' ).render(),
|
||||
expected: mw.template.get( 'test.DiscussionTools', 'cases/en-big-oldparser/en-big-oldparser-reply.html' ).render(),
|
||||
config: require( './data/enwiki-config.json' ),
|
||||
data: require( './data/enwiki-data.json' )
|
||||
},
|
||||
{
|
||||
name: 'Signatures in funny places',
|
||||
dom: mw.template.get( 'test.DiscussionTools', 'cases/signatures-funny/signatures-funny.html' ).render(),
|
||||
expected: mw.template.get( 'test.DiscussionTools', 'cases/signatures-funny/signatures-funny-reply.html' ).render(),
|
||||
config: require( './data/enwiki-config.json' ),
|
||||
data: require( './data/enwiki-data.json' )
|
||||
}
|
||||
];
|
||||
|
||||
fixture = document.getElementById( 'qunit-fixture' );
|
||||
|
||||
for ( i = 0; i < cases.length; i++ ) {
|
||||
utils.overrideMwConfig( cases[ i ].config );
|
||||
utils.overrideParserData( cases[ i ].data );
|
||||
|
||||
$( fixture ).empty().append( cases[ i ].expected );
|
||||
expectedHtml = fixture.innerHTML;
|
||||
|
||||
$( fixture ).empty().append( cases[ i ].dom.clone() );
|
||||
|
||||
comments = parser.getComments( fixture );
|
||||
parser.groupThreads( comments );
|
||||
|
||||
// Add a reply link to every comment.
|
||||
for ( j = 0; j < comments.length; j++ ) {
|
||||
if ( comments[ j ].type === 'heading' ) {
|
||||
continue;
|
||||
}
|
||||
linkNode = document.createElement( 'a' );
|
||||
linkNode.textContent = 'Reply';
|
||||
linkNode.href = '#';
|
||||
modifier.addReplyLink( comments[ j ], linkNode );
|
||||
}
|
||||
|
||||
// Uncomment this to get updated content for the the "reply HTML" files, for copy/paste:
|
||||
// console.log( fixture.innerHTML );
|
||||
|
||||
actualHtml = fixture.innerHTML.trim();
|
||||
|
||||
assert.strictEqual(
|
||||
actualHtml,
|
||||
expectedHtml,
|
||||
cases[ i ].name
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
|
Loading…
Reference in a new issue