mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-12-03 20:46:48 +00:00
31b26a5bec
When adding a reply, we take a node at the end of the previous comment, compare that comment's indentation level to the expected indentation level of the reply, and add (or remove) that number of wrapper lists. The existing code did not consider that comments may have lists within them, and so the indentation of that node may not match the indentation of the comment. Bug: T252702 Change-Id: Icc5ff19783d2b213bff99f283cb0599a8b5c1ab4
112 lines
3.1 KiB
JavaScript
112 lines
3.1 KiB
JavaScript
/**
|
|
* @external CommentItem
|
|
*/
|
|
|
|
var
|
|
utils = require( 'ext.discussionTools.init' ).utils;
|
|
|
|
module.exports = {};
|
|
|
|
/* eslint-disable qunit/no-commented-tests */
|
|
/**
|
|
* Create a QUnit environment that will automatically restore the parser data and config at the end
|
|
* of every test (so that we can use #overrideParserData and #overrideMwConfig without thinking
|
|
* about cleaning it up).
|
|
*
|
|
* @return {Object}
|
|
*/
|
|
module.exports.newEnvironment = function () {
|
|
var originalParserData = $.extend(
|
|
{},
|
|
mw.loader.moduleRegistry[ 'ext.discussionTools.init' ].packageExports[ 'parser/data.json' ]
|
|
);
|
|
|
|
return QUnit.newMwEnvironment( {
|
|
afterEach: function () {
|
|
module.exports.overrideParserData( originalParserData );
|
|
// mw.config is restored by QUnit.newMwEnvironment already
|
|
}
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* Override the parser data with the given data. Used for testing different languages etc.
|
|
*
|
|
* @param {Object} data
|
|
*/
|
|
module.exports.overrideParserData = function ( data ) {
|
|
$.extend(
|
|
mw.loader.moduleRegistry[ 'ext.discussionTools.init' ].packageExports[ 'parser/data.json' ],
|
|
data
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Override mw.config with the given data. Used for testing different languages etc.
|
|
*
|
|
* @param {Object} config
|
|
*/
|
|
module.exports.overrideMwConfig = function ( config ) {
|
|
$.extend(
|
|
mw.config.values,
|
|
config
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Get the offset path from ancestor to offset in descendant
|
|
*
|
|
* @copyright 2011-2019 VisualEditor Team and others; see http://ve.mit-license.org
|
|
*
|
|
* @param {Node} ancestor The ancestor node
|
|
* @param {Node} node The descendant node
|
|
* @param {number} nodeOffset The offset in the descendant node
|
|
* @return {number[]} The offset path
|
|
*/
|
|
function getOffsetPath( ancestor, node, nodeOffset ) {
|
|
var path = [ nodeOffset ];
|
|
while ( node !== ancestor ) {
|
|
if ( node.parentNode === null ) {
|
|
// eslint-disable-next-line no-console
|
|
console.log( node, 'is not a descendant of', ancestor );
|
|
throw new Error( 'Not a descendant' );
|
|
}
|
|
path.unshift( utils.childIndexOf( node ) );
|
|
node = node.parentNode;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
/**
|
|
* Massage comment data to make it serializable as JSON.
|
|
*
|
|
* @param {CommentItem} parent Comment item; modified in-place
|
|
* @param {Node} root Ancestor node of all comments
|
|
*/
|
|
module.exports.serializeComments = function ( parent, root ) {
|
|
// Can't serialize circular structures to JSON
|
|
delete parent.parent;
|
|
|
|
// Can't serialize the DOM nodes involved in the range,
|
|
// instead use their offsets within their parent nodes
|
|
parent.range = [
|
|
getOffsetPath( root, parent.range.startContainer, parent.range.startOffset ).join( '/' ),
|
|
getOffsetPath( root, parent.range.endContainer, parent.range.endOffset ).join( '/' )
|
|
];
|
|
if ( parent.signatureRanges ) {
|
|
parent.signatureRanges = parent.signatureRanges.map( function ( range ) {
|
|
return [
|
|
getOffsetPath( root, range.startContainer, range.startOffset ).join( '/' ),
|
|
getOffsetPath( root, range.endContainer, range.endOffset ).join( '/' )
|
|
];
|
|
} );
|
|
}
|
|
|
|
// Unimportant
|
|
delete parent.rootNode;
|
|
|
|
parent.replies.forEach( function ( comment ) {
|
|
module.exports.serializeComments( comment, root );
|
|
} );
|
|
};
|