2019-11-05 14:13:18 +00:00
|
|
|
'use strict';
|
2020-05-22 16:26:05 +00:00
|
|
|
/* global $:off */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @external CommentItem
|
|
|
|
*/
|
2019-11-05 14:13:18 +00:00
|
|
|
|
2020-03-08 14:32:38 +00:00
|
|
|
var
|
|
|
|
utils = require( './utils.js' );
|
2019-11-05 14:13:18 +00:00
|
|
|
|
2020-05-11 15:47:04 +00:00
|
|
|
/**
|
|
|
|
* Add an attribute to a list item to remove pre-whitespace in Parsoid
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} listItem List item element
|
|
|
|
*/
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
function whitespaceParsoidHack( listItem ) {
|
2019-11-13 14:36:36 +00:00
|
|
|
// HACK: Setting data-parsoid removes the whitespace after the list item,
|
|
|
|
// which makes nested lists work.
|
|
|
|
// This is undocumented behaviour and probably very fragile.
|
|
|
|
listItem.setAttribute( 'data-parsoid', '{}' );
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 22:24:14 +00:00
|
|
|
/**
|
|
|
|
* Remove extra linebreaks from a wikitext string
|
|
|
|
*
|
|
|
|
* @param {string} wikitext Wikitext
|
|
|
|
* @return {string}
|
|
|
|
*/
|
|
|
|
function sanitizeWikitextLinebreaks( wikitext ) {
|
2020-07-15 21:43:56 +00:00
|
|
|
return utils.htmlTrim( wikitext )
|
2020-06-26 22:24:14 +00:00
|
|
|
.replace( /\r/g, '\n' )
|
|
|
|
.replace( /\n+/g, '\n' );
|
|
|
|
}
|
|
|
|
|
2020-03-02 18:50:36 +00:00
|
|
|
/**
|
|
|
|
* Given a comment and a reply link, add the reply link to its document's DOM tree, at the end of
|
|
|
|
* the comment.
|
|
|
|
*
|
2020-07-19 19:47:44 +00:00
|
|
|
* @param {CommentItem} comment Comment item
|
2020-03-02 18:50:36 +00:00
|
|
|
* @param {HTMLElement} linkNode Reply link
|
|
|
|
*/
|
|
|
|
function addReplyLink( comment, linkNode ) {
|
|
|
|
var target = comment.range.endContainer;
|
|
|
|
|
2020-04-02 21:39:18 +00:00
|
|
|
// Skip to the end of the "paragraph". This only looks at tag names and can be fooled by CSS, but
|
|
|
|
// avoiding that would be more difficult and slower.
|
2020-07-22 19:01:13 +00:00
|
|
|
while ( target.nextSibling && !( target.nextSibling instanceof HTMLElement && ve.isBlockElement( target.nextSibling ) ) ) {
|
2020-03-02 18:50:36 +00:00
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
/**
|
|
|
|
* Given a comment, add a list item to its document's DOM tree, inside of which a reply to said
|
|
|
|
* comment can be added.
|
|
|
|
*
|
|
|
|
* The DOM tree is suitably rearranged to ensure correct indentation level of the reply (wrapper
|
|
|
|
* nodes are added, and other nodes may be moved around).
|
|
|
|
*
|
2020-07-19 19:47:44 +00:00
|
|
|
* @param {CommentItem} comment Comment item
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
* @return {HTMLElement}
|
|
|
|
*/
|
|
|
|
function addListItem( comment ) {
|
|
|
|
var
|
2020-08-04 00:04:20 +00:00
|
|
|
curComment, curLevel, desiredLevel, itemType, listType,
|
|
|
|
target, parent, covered, list, item, newNode,
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
listTypeMap = {
|
|
|
|
li: 'ul',
|
|
|
|
dd: 'dl'
|
|
|
|
};
|
|
|
|
|
|
|
|
// 1. Start at given comment
|
|
|
|
// 2. Skip past all comments with level greater than the given
|
|
|
|
// (or in other words, all replies, and replies to replies, and so on)
|
|
|
|
// 3. Add comment with level of the given comment plus 1
|
|
|
|
|
2020-05-11 15:47:04 +00:00
|
|
|
curComment = comment;
|
|
|
|
while ( curComment.replies.length ) {
|
|
|
|
curComment = curComment.replies[ curComment.replies.length - 1 ];
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 00:04:20 +00:00
|
|
|
// Tag names for lists and items we're going to insert
|
|
|
|
// TODO Add an option to prefer bulleted lists (ul/li)
|
|
|
|
itemType = 'dd';
|
|
|
|
listType = listTypeMap[ itemType ];
|
|
|
|
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
desiredLevel = comment.level + 1;
|
2020-05-11 15:47:04 +00:00
|
|
|
target = curComment.range.endContainer;
|
2020-03-02 18:50:36 +00:00
|
|
|
|
2020-04-02 21:39:18 +00:00
|
|
|
// Skip to the end of the "paragraph". This only looks at tag names and can be fooled by CSS, but
|
|
|
|
// avoiding that would be more difficult and slower.
|
2020-07-22 19:01:13 +00:00
|
|
|
while ( target.nextSibling && !( target.nextSibling instanceof HTMLElement && ve.isBlockElement( target.nextSibling ) ) ) {
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
target = target.nextSibling;
|
|
|
|
}
|
|
|
|
|
2020-03-02 18:50:36 +00:00
|
|
|
// target is a text node or an inline element at the end of a "paragraph" (not necessarily paragraph node).
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
// 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.
|
2020-03-08 14:32:38 +00:00
|
|
|
parent = utils.closestElement( target, [ 'li', 'dd', 'p' ] ) || target.parentNode;
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
while ( target.parentNode !== parent ) {
|
|
|
|
target = target.parentNode;
|
|
|
|
}
|
|
|
|
// parent is a list item or paragraph (hopefully)
|
|
|
|
// target is an inline node within it
|
|
|
|
|
2020-07-29 23:57:51 +00:00
|
|
|
// Instead of just using curComment.level, consider indentation of lists within the
|
|
|
|
// comment (T252702)
|
|
|
|
curLevel = utils.getIndentLevel( target, curComment.rootNode ) + 1;
|
|
|
|
|
2020-05-11 15:47:04 +00:00
|
|
|
if ( curLevel < desiredLevel ) {
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
// Insert more lists after the target to increase nesting.
|
2019-11-13 14:36:36 +00:00
|
|
|
|
2020-04-28 19:20:23 +00:00
|
|
|
// If the comment is fully covered by some wrapper element, insert replies outside that wrapper.
|
|
|
|
// This will often just be a paragraph node (<p>), but it can be a <div> or <table> that serves
|
|
|
|
// as some kind of a fancy frame, which are often used for barnstars and announcements.
|
2020-06-16 14:08:01 +00:00
|
|
|
covered = utils.getFullyCoveredSiblings( curComment );
|
|
|
|
if ( curLevel === 1 && covered ) {
|
|
|
|
target = covered[ covered.length - 1 ];
|
2020-04-28 19:20:23 +00:00
|
|
|
parent = target.parentNode;
|
|
|
|
}
|
|
|
|
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
// If we can't insert a list directly inside this element, insert after it.
|
2020-06-16 14:08:01 +00:00
|
|
|
// TODO Figure out if this is still needed, the wrapper check above should handle all cases
|
2020-04-25 17:36:48 +00:00
|
|
|
if ( parent.tagName.toLowerCase() === 'p' || parent.tagName.toLowerCase() === 'pre' ) {
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
parent = parent.parentNode;
|
|
|
|
target = target.parentNode;
|
|
|
|
}
|
|
|
|
|
2020-07-22 19:01:13 +00:00
|
|
|
// Parsoid puts HTML comments which appear at the end of the line in wikitext outside the paragraph,
|
|
|
|
// but we usually shouldn't insert replies between the paragraph and such comments. (T257651)
|
|
|
|
if ( target.nextSibling && target.nextSibling instanceof Comment ) {
|
|
|
|
target = target.nextSibling;
|
|
|
|
}
|
|
|
|
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
// Insert required number of wrappers
|
2020-05-11 15:47:04 +00:00
|
|
|
while ( curLevel < desiredLevel ) {
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
list = target.ownerDocument.createElement( listType );
|
2020-02-24 21:58:51 +00:00
|
|
|
list.discussionToolsModified = 'new';
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
item = target.ownerDocument.createElement( itemType );
|
2020-02-24 21:58:51 +00:00
|
|
|
item.discussionToolsModified = 'new';
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
whitespaceParsoidHack( item );
|
|
|
|
|
|
|
|
parent.insertBefore( list, target.nextSibling );
|
|
|
|
list.appendChild( item );
|
|
|
|
|
|
|
|
target = item;
|
|
|
|
parent = list;
|
2020-05-11 15:47:04 +00:00
|
|
|
curLevel++;
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
}
|
2020-06-04 18:48:58 +00:00
|
|
|
} else {
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
// Split the ancestor nodes after the target to decrease nesting.
|
|
|
|
|
|
|
|
do {
|
|
|
|
// If target is the last child of its parent, no need to split it
|
|
|
|
if ( target.nextSibling ) {
|
|
|
|
// Create new identical node after the parent
|
|
|
|
newNode = parent.cloneNode( false );
|
2020-02-24 21:58:51 +00:00
|
|
|
parent.discussionToolsModified = 'split';
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
parent.parentNode.insertBefore( newNode, parent.nextSibling );
|
|
|
|
|
|
|
|
// Move nodes following target to the new node
|
|
|
|
while ( target.nextSibling ) {
|
|
|
|
newNode.appendChild( target.nextSibling );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
target = parent;
|
|
|
|
parent = parent.parentNode;
|
|
|
|
|
|
|
|
// Decrease nesting level if we escaped outside of a list
|
|
|
|
if ( listTypeMap[ target.tagName.toLowerCase() ] ) {
|
2020-05-11 15:47:04 +00:00
|
|
|
curLevel--;
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
}
|
2020-05-11 15:47:04 +00:00
|
|
|
} while ( curLevel >= desiredLevel );
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
|
|
|
|
// parent is now a list, target is a list item
|
2020-08-04 00:04:20 +00:00
|
|
|
if ( itemType === target.tagName.toLowerCase() ) {
|
|
|
|
item = target.ownerDocument.createElement( itemType );
|
|
|
|
item.discussionToolsModified = 'new';
|
|
|
|
whitespaceParsoidHack( item );
|
|
|
|
parent.insertBefore( item, target.nextSibling );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// This is the wrong type of list, split it one more time
|
|
|
|
|
|
|
|
// If target is the last child of its parent, no need to split it
|
|
|
|
if ( target.nextSibling ) {
|
|
|
|
// Create new identical node after the parent
|
|
|
|
newNode = parent.cloneNode( false );
|
|
|
|
parent.discussionToolsModified = 'split';
|
|
|
|
parent.parentNode.insertBefore( newNode, parent.nextSibling );
|
|
|
|
|
|
|
|
// Move nodes following target to the new node
|
|
|
|
while ( target.nextSibling ) {
|
|
|
|
newNode.appendChild( target.nextSibling );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
target = parent;
|
|
|
|
parent = parent.parentNode;
|
|
|
|
|
|
|
|
// Insert a list of the right type in the middle
|
|
|
|
list = target.ownerDocument.createElement( listType );
|
|
|
|
list.discussionToolsModified = 'new';
|
|
|
|
item = target.ownerDocument.createElement( itemType );
|
|
|
|
item.discussionToolsModified = 'new';
|
|
|
|
whitespaceParsoidHack( item );
|
|
|
|
|
|
|
|
parent.insertBefore( list, target.nextSibling );
|
|
|
|
list.appendChild( item );
|
|
|
|
}
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
2020-02-24 21:58:51 +00:00
|
|
|
/**
|
|
|
|
* Undo the effects of #addListItem, also removing or merging any affected parent nodes.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} node
|
|
|
|
*/
|
2020-05-15 00:23:50 +00:00
|
|
|
function removeAddedListItem( node ) {
|
2020-02-24 21:58:51 +00:00
|
|
|
var nextNode;
|
|
|
|
|
|
|
|
while ( node && node.discussionToolsModified ) {
|
|
|
|
if ( node.discussionToolsModified === 'new' ) {
|
|
|
|
nextNode = node.previousSibling || node.parentNode;
|
|
|
|
|
|
|
|
// Remove this node
|
|
|
|
delete node.discussionToolsModified;
|
|
|
|
node.parentNode.removeChild( node );
|
|
|
|
|
|
|
|
} else if ( node.discussionToolsModified === 'split' ) {
|
|
|
|
// Children might be split too, if so, descend into them afterwards
|
|
|
|
if ( node.lastChild && node.lastChild.discussionToolsModified === 'split' ) {
|
|
|
|
node.discussionToolsModified = 'done';
|
|
|
|
nextNode = node.lastChild;
|
|
|
|
} else {
|
|
|
|
delete node.discussionToolsModified;
|
|
|
|
nextNode = node.parentNode;
|
|
|
|
}
|
|
|
|
// Merge the following sibling node back into this one
|
|
|
|
while ( node.nextSibling.firstChild ) {
|
|
|
|
node.appendChild( node.nextSibling.firstChild );
|
|
|
|
}
|
|
|
|
node.parentNode.removeChild( node.nextSibling );
|
|
|
|
|
|
|
|
} else {
|
|
|
|
nextNode = node.parentNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
node = nextNode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-27 16:23:27 +00:00
|
|
|
/**
|
|
|
|
* Unwrap a top level list, converting list item text to paragraphs
|
|
|
|
*
|
2020-05-26 20:47:46 +00:00
|
|
|
* Assumes that the list has a parent node.
|
2020-04-27 16:23:27 +00:00
|
|
|
*
|
2020-06-24 18:19:06 +00:00
|
|
|
* @param {Node} list DOM node, will be wrapepd if it is a list element (dl/ol/ul)
|
2020-04-27 16:23:27 +00:00
|
|
|
*/
|
|
|
|
function unwrapList( list ) {
|
2020-06-03 12:53:36 +00:00
|
|
|
var p, insertBefore,
|
2020-04-27 16:23:27 +00:00
|
|
|
doc = list.ownerDocument,
|
2020-05-26 20:47:46 +00:00
|
|
|
container = list.parentNode,
|
|
|
|
referenceNode = list;
|
|
|
|
|
2020-06-24 18:19:06 +00:00
|
|
|
if ( !(
|
|
|
|
list.nodeType === Node.ELEMENT_NODE && (
|
|
|
|
list.tagName.toLowerCase() === 'dl' ||
|
|
|
|
list.tagName.toLowerCase() === 'ol' ||
|
|
|
|
list.tagName.toLowerCase() === 'ul'
|
|
|
|
)
|
|
|
|
) ) {
|
|
|
|
// Not a list, leave alone (e.g. auto-generated ref block)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-26 20:47:46 +00:00
|
|
|
// If the whole list is a template return it unmodified (T253150)
|
|
|
|
if ( utils.getTranscludedFromElement( list ) ) {
|
|
|
|
return;
|
|
|
|
}
|
2020-04-27 16:23:27 +00:00
|
|
|
|
|
|
|
while ( list.firstChild ) {
|
|
|
|
if ( list.firstChild.nodeType === Node.ELEMENT_NODE ) {
|
|
|
|
// Move <dd> contents to <p>
|
|
|
|
p = doc.createElement( 'p' );
|
|
|
|
while ( list.firstChild.firstChild ) {
|
|
|
|
// If contents is a block element, place outside the paragraph
|
|
|
|
// and start a new paragraph after
|
2020-07-22 19:01:13 +00:00
|
|
|
if ( list.firstChild.firstChild instanceof HTMLElement && ve.isBlockElement( list.firstChild.firstChild ) ) {
|
2020-04-27 16:23:27 +00:00
|
|
|
if ( p.firstChild ) {
|
2020-06-03 12:53:36 +00:00
|
|
|
insertBefore = referenceNode.nextSibling;
|
2020-05-26 20:47:46 +00:00
|
|
|
referenceNode = p;
|
2020-06-03 12:53:36 +00:00
|
|
|
container.insertBefore( p, insertBefore );
|
2020-04-27 16:23:27 +00:00
|
|
|
}
|
2020-06-03 12:53:36 +00:00
|
|
|
insertBefore = referenceNode.nextSibling;
|
2020-05-26 20:47:46 +00:00
|
|
|
referenceNode = list.firstChild.firstChild;
|
2020-06-03 12:53:36 +00:00
|
|
|
container.insertBefore( list.firstChild.firstChild, insertBefore );
|
2020-04-27 16:23:27 +00:00
|
|
|
p = doc.createElement( 'p' );
|
|
|
|
} else {
|
|
|
|
p.appendChild( list.firstChild.firstChild );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( p.firstChild ) {
|
2020-06-03 12:53:36 +00:00
|
|
|
insertBefore = referenceNode.nextSibling;
|
2020-05-26 20:47:46 +00:00
|
|
|
referenceNode = p;
|
2020-06-03 12:53:36 +00:00
|
|
|
container.insertBefore( p, insertBefore );
|
2020-04-27 16:23:27 +00:00
|
|
|
}
|
|
|
|
list.removeChild( list.firstChild );
|
|
|
|
} else {
|
|
|
|
// Text node / comment node, probably empty
|
2020-06-03 12:53:36 +00:00
|
|
|
insertBefore = referenceNode.nextSibling;
|
2020-05-26 20:47:46 +00:00
|
|
|
referenceNode = list.firstChild;
|
2020-06-03 12:53:36 +00:00
|
|
|
container.insertBefore( list.firstChild, insertBefore );
|
2020-04-27 16:23:27 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-26 20:47:46 +00:00
|
|
|
container.removeChild( list );
|
2020-04-27 16:23:27 +00:00
|
|
|
}
|
|
|
|
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
/**
|
|
|
|
* Add another list item after the given one.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} previousItem
|
|
|
|
* @return {HTMLElement}
|
|
|
|
*/
|
|
|
|
function addSiblingListItem( previousItem ) {
|
2020-06-10 16:22:27 +00:00
|
|
|
var listItem = previousItem.ownerDocument.createElement( previousItem.tagName );
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
whitespaceParsoidHack( listItem );
|
|
|
|
previousItem.parentNode.insertBefore( listItem, previousItem.nextSibling );
|
2019-11-05 14:13:18 +00:00
|
|
|
return listItem;
|
|
|
|
}
|
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
function createWikitextNode( doc, wt ) {
|
|
|
|
var span = doc.createElement( 'span' );
|
|
|
|
|
|
|
|
span.setAttribute( 'typeof', 'mw:Transclusion' );
|
|
|
|
span.setAttribute( 'data-mw', JSON.stringify( { parts: [ wt ] } ) );
|
|
|
|
|
|
|
|
return span;
|
|
|
|
}
|
|
|
|
|
2020-07-15 21:43:56 +00:00
|
|
|
/**
|
|
|
|
* Check whether wikitext contains a user signature.
|
|
|
|
*
|
|
|
|
* @param {string} wikitext
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
function isWikitextSigned( wikitext ) {
|
|
|
|
wikitext = utils.htmlTrim( wikitext );
|
|
|
|
// Contains ~~~~ (four tildes), but not ~~~~~ (five tildes), at the end.
|
|
|
|
return /([^~]|^)~~~~$/.test( wikitext );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether HTML node contains a user signature.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} container
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
function isHtmlSigned( container ) {
|
|
|
|
var matches, lastSig, node;
|
|
|
|
// Good enough?…
|
|
|
|
matches = container.querySelectorAll( 'span[typeof="mw:Transclusion"][data-mw*="~~~~"]' );
|
|
|
|
if ( matches.length === 0 ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
lastSig = matches[ matches.length - 1 ];
|
|
|
|
// Signature must be at the end of the comment - there must be no sibling following this node, or its parents
|
|
|
|
node = lastSig;
|
|
|
|
while ( node ) {
|
|
|
|
// Skip over whitespace nodes
|
|
|
|
while (
|
|
|
|
node.nextSibling &&
|
|
|
|
node.nextSibling.nodeType === Node.TEXT_NODE &&
|
|
|
|
utils.htmlTrim( node.nextSibling.textContent ) === ''
|
|
|
|
) {
|
|
|
|
node = node.nextSibling;
|
|
|
|
}
|
|
|
|
if ( node.nextSibling ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
node = node.parentNode;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Append a user signature to the comment in the container.
|
|
|
|
*
|
|
|
|
* @param {HTMLElement} container
|
|
|
|
*/
|
|
|
|
function appendSignature( container ) {
|
|
|
|
var doc = container.ownerDocument;
|
|
|
|
|
|
|
|
// If the last node isn't a paragraph (e.g. it's a list created in visual mode), then
|
|
|
|
// add another paragraph to contain the signature.
|
|
|
|
if ( container.lastChild.nodeName.toLowerCase() !== 'p' ) {
|
|
|
|
container.appendChild( doc.createElement( 'p' ) );
|
|
|
|
}
|
|
|
|
// Sign the last line
|
|
|
|
// TODO: When we implement posting new topics, the leading space will create an indent-pre
|
|
|
|
container.lastChild.appendChild(
|
|
|
|
createWikitextNode( doc, mw.msg( 'discussiontools-signature-prefix' ) + '~~~~' )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-26 22:00:34 +00:00
|
|
|
/**
|
|
|
|
* Add a reply to a specific comment
|
|
|
|
*
|
|
|
|
* @param {CommentItem} comment Comment being replied to
|
|
|
|
* @param {HTMLElement} container Container of comment DOM nodes
|
|
|
|
*/
|
|
|
|
function addReply( comment, container ) {
|
|
|
|
var newParsoidItem;
|
|
|
|
|
|
|
|
// Transfer comment DOM to Parsoid DOM
|
|
|
|
// Wrap every root node of the document in a new list item (dd/li).
|
|
|
|
// In wikitext mode every root node is a paragraph.
|
|
|
|
// In visual mode the editor takes care of preventing problematic nodes
|
|
|
|
// like <table> or <h2> from ever occurring in the comment.
|
|
|
|
while ( container.childNodes.length ) {
|
|
|
|
if ( !newParsoidItem ) {
|
|
|
|
newParsoidItem = addListItem( comment );
|
|
|
|
} else {
|
|
|
|
newParsoidItem = addSiblingListItem( newParsoidItem );
|
|
|
|
}
|
|
|
|
newParsoidItem.appendChild( container.firstChild );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
/**
|
|
|
|
* Create a container of comment DOM nodes from wikitext
|
|
|
|
*
|
|
|
|
* @param {CommentItem} comment Comment being replied to
|
|
|
|
* @param {string} wikitext Wikitext
|
|
|
|
*/
|
|
|
|
function addWikitextReply( comment, wikitext ) {
|
|
|
|
var doc = comment.range.endContainer.ownerDocument,
|
|
|
|
container = doc.createElement( 'div' );
|
2020-06-26 22:24:14 +00:00
|
|
|
|
2020-07-15 21:43:56 +00:00
|
|
|
wikitext = sanitizeWikitextLinebreaks( wikitext );
|
2020-06-26 22:24:14 +00:00
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
wikitext.split( '\n' ).forEach( function ( line ) {
|
|
|
|
var p = doc.createElement( 'p' );
|
|
|
|
p.appendChild( createWikitextNode( doc, line ) );
|
|
|
|
container.appendChild( p );
|
|
|
|
} );
|
2020-07-15 21:43:56 +00:00
|
|
|
|
|
|
|
if ( !isWikitextSigned( wikitext ) ) {
|
|
|
|
appendSignature( container );
|
|
|
|
}
|
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
addReply( comment, container );
|
|
|
|
}
|
2019-11-05 14:13:18 +00:00
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
/**
|
|
|
|
* Create a container of comment DOM nodes from HTML
|
|
|
|
*
|
|
|
|
* @param {CommentItem} comment Comment being replied to
|
|
|
|
* @param {string} html HTML
|
|
|
|
*/
|
|
|
|
function addHtmlReply( comment, html ) {
|
|
|
|
var doc = comment.range.endContainer.ownerDocument,
|
|
|
|
childNodeList,
|
|
|
|
container = doc.createElement( 'div' );
|
|
|
|
|
|
|
|
container.innerHTML = html;
|
|
|
|
// Remove empty lines
|
|
|
|
// This should really be anything that serializes to empty string in wikitext,
|
|
|
|
// (e.g. <h2></h2>) but this will catch most cases
|
|
|
|
// Create a non-live child node list, so we don't have to worry about it changing
|
|
|
|
// as nodes are removed.
|
|
|
|
childNodeList = Array.prototype.slice.call( container.childNodes );
|
|
|
|
childNodeList.forEach( function ( node ) {
|
|
|
|
if ( node.nodeName.toLowerCase() === 'p' && !utils.htmlTrim( node.innerHTML ) ) {
|
|
|
|
container.removeChild( node );
|
|
|
|
}
|
|
|
|
} );
|
2020-07-15 21:43:56 +00:00
|
|
|
|
|
|
|
if ( !isHtmlSigned( container ) ) {
|
|
|
|
appendSignature( container );
|
2020-06-26 22:37:35 +00:00
|
|
|
}
|
2020-07-15 21:43:56 +00:00
|
|
|
|
2020-06-26 22:37:35 +00:00
|
|
|
addReply( comment, container );
|
2019-11-05 14:13:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
2020-03-02 18:50:36 +00:00
|
|
|
addReplyLink: addReplyLink,
|
2019-11-05 14:13:18 +00:00
|
|
|
addListItem: addListItem,
|
2020-05-15 00:23:50 +00:00
|
|
|
removeAddedListItem: removeAddedListItem,
|
Pick reply insertion point based on parser tree, not DOM tree
I don't like that I had to special-case `<p>` tags (top-level
comments) in this code. I feel like it should be possible to handle
top-level comments and replies in a generic way, but I couldn't find
a way to do it that actually worked.
Notes about changes to the behavior, based on the test cases:
* Given a top-level comment A, if there was a "list gap" in the
replies to it: previously new replies would be incorrectly added at
the location of the gap; now they are added after the last reply.
(T242822)
Example: "pl", comment at "08:23, 29 wrz 2018 (CEST)"
* Given a top-level comment A and a reply to it B that skips an
indentation level: previously new replies to A would be added with
the same indentation level as B; now they are added with the
indentation level of A plus one. (The old behavior wasn't a bug, and
this is an accidental effect of other changes, but it seems okay.)
Example: "pl", comment at "03:22, 30 wrz 2018 (CEST)"
and reply at "09:43, 30 wrz 2018 (CEST)"
* Given a top-level comment A, a reply to it B, and a following
top-level comment C that starts at the same indentation level as B:
previously new replies to A would be incorrectly added in the middle
of the comment C, due to the DOM list structure; now they are added
before C. (T241391)
(It seems that comment C was supposed to be a multi-line reply that
was wrongly indented. Unfortunately we have no way to distinguish
this case from a top-level multi-line comment that just happens to
start with a bullet list.)
Example: "pl", comments at "03:36, 24 paź 2018 (CEST)",
"08:35, 24 paź 2018 (CEST)", "17:14, 24 paź 2018 (CEST)"
* In the "en" example, there are some other changes where funnily
nested tags result in slightly different results with the new code.
They don't look important.
* In rare cases, we must split an existing list to add a reply in the
right place. (Basically add `</ul>` before the reply and `<ul>`
after, but it's a bit awkward in DOM terms.)
Example: split-list.html, comment "aaa"; also split-list2.html
(which is the result of saving the previous reply), comment "aaa"
* The modifier can no longer generate DOM that is invalid HTML, fixing
a FIXME in modifier.test.js (or at least, it doesn't happen in these
test cases any more).
Bug: T241391
Bug: T242822
Change-Id: I2a70db01e9a8916c5636bc59ea8490166966d5ec
2020-01-15 06:09:13 +00:00
|
|
|
addSiblingListItem: addSiblingListItem,
|
2020-04-27 16:23:27 +00:00
|
|
|
unwrapList: unwrapList,
|
2020-06-26 22:37:35 +00:00
|
|
|
createWikitextNode: createWikitextNode,
|
|
|
|
addWikitextReply: addWikitextReply,
|
2020-06-26 22:24:14 +00:00
|
|
|
addHtmlReply: addHtmlReply,
|
2020-07-15 21:43:56 +00:00
|
|
|
isWikitextSigned: isWikitextSigned,
|
|
|
|
isHtmlSigned: isHtmlSigned,
|
2020-06-26 22:24:14 +00:00
|
|
|
sanitizeWikitextLinebreaks: sanitizeWikitextLinebreaks
|
2019-11-05 14:13:18 +00:00
|
|
|
};
|