mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-27 17:51:09 +00:00
Merge "Highlight comment after saving"
This commit is contained in:
commit
a7db61d43f
|
@ -8,6 +8,7 @@
|
|||
"OO": "readonly",
|
||||
"ve": "readonly",
|
||||
"require": "readonly",
|
||||
"module": "readonly"
|
||||
"module": "readonly",
|
||||
"RangeFix": "readonly"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
],
|
||||
"styles": "dt.init.less",
|
||||
"dependencies": [
|
||||
"rangefix",
|
||||
"mediawiki.Uri",
|
||||
"ext.discussionTools.parser",
|
||||
"ext.discussionTools.modifier",
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
var $pageContainer,
|
||||
var $pageContainer, pageComments, pageThreads,
|
||||
scrollPadding = { top: 10, bottom: 10 },
|
||||
replyWidgetPromise = mw.loader.using( 'ext.discussionTools.ReplyWidget' );
|
||||
|
||||
function getReplyIndex( comment ) {
|
||||
var commentIndex = pageComments.indexOf( comment );
|
||||
|
||||
function countReplies( c ) {
|
||||
var count = c.replies.length;
|
||||
c.replies.forEach( function ( r ) {
|
||||
count += countReplies( r );
|
||||
} );
|
||||
return count;
|
||||
}
|
||||
|
||||
return commentIndex + countReplies( comment ) + 1;
|
||||
}
|
||||
|
||||
function setupComment( comment ) {
|
||||
var $replyLink, widgetPromise, newList, newListItem,
|
||||
$tsNode = $( comment.range.endContainer );
|
||||
|
@ -18,7 +32,11 @@ function setupComment( comment ) {
|
|||
// TODO: i18n
|
||||
.text( 'Reply' )
|
||||
.on( 'click', function () {
|
||||
var $link = $( this );
|
||||
var $link = $( this ),
|
||||
userCommentsBeforeReply = pageComments.slice( 0, getReplyIndex( comment ) )
|
||||
.filter( function ( c ) {
|
||||
return c.author === mw.user.getName();
|
||||
} ).length;
|
||||
|
||||
$link.addClass( 'dt-init-replylink-active' );
|
||||
// TODO: Allow users to use multiple reply widgets simlutaneously
|
||||
|
@ -33,7 +51,7 @@ function setupComment( comment ) {
|
|||
$( newListItem ).text( 'Loading...' );
|
||||
widgetPromise = replyWidgetPromise.then( function () {
|
||||
var replyWidget = new mw.dt.ui.ReplyWidget(
|
||||
comment,
|
||||
comment, userCommentsBeforeReply,
|
||||
{
|
||||
// TODO: Remove placeholder
|
||||
doc: '<p>Reply to ' + comment.author + '</p>',
|
||||
|
@ -110,22 +128,59 @@ function postReply( widget, parsoidData ) {
|
|||
} );
|
||||
}
|
||||
|
||||
function init( $container ) {
|
||||
var pageComments, pageThreads, parsoidPromise, parsoidComments, parsoidDoc,
|
||||
function highlight( comment ) {
|
||||
var padding = 5,
|
||||
containerRect = RangeFix.getBoundingClientRect( $pageContainer[ 0 ] ),
|
||||
rect = RangeFix.getBoundingClientRect( comment.range ),
|
||||
$highlight = $( '<div>' ).addClass( 'dt-init-highlight' );
|
||||
|
||||
$highlight.css( {
|
||||
top: rect.top - containerRect.top - padding,
|
||||
left: rect.left - containerRect.left - padding,
|
||||
width: rect.width + ( padding * 2 ),
|
||||
height: rect.height + ( padding * 2 )
|
||||
} );
|
||||
|
||||
setTimeout( function () {
|
||||
$highlight.addClass( 'dt-init-highlight-fade' );
|
||||
setTimeout( function () {
|
||||
$highlight.remove();
|
||||
}, 500 );
|
||||
}, 500 );
|
||||
|
||||
$pageContainer.prepend( $highlight );
|
||||
}
|
||||
|
||||
function init( $container, state ) {
|
||||
var parsoidPromise, parsoidComments, parsoidDoc,
|
||||
parsoidPageData = {
|
||||
pageName: mw.config.get( 'wgRelevantPageName' ),
|
||||
oldId: mw.config.get( 'wgRevisionId' ),
|
||||
token: mw.user.tokens.get( 'csrfToken' )
|
||||
};
|
||||
|
||||
state = state || {};
|
||||
$pageContainer = $container;
|
||||
pageComments = mw.dt.parser.getComments( $pageContainer[ 0 ] );
|
||||
pageThreads = mw.dt.parser.groupThreads( pageComments );
|
||||
pageThreads.forEach( traverseNode );
|
||||
|
||||
$pageContainer.addClass( 'dt-init-done' );
|
||||
$pageContainer.removeClass( 'dt-init-replylink-open' );
|
||||
|
||||
// For debugging
|
||||
mw.dt.pageThreads = pageThreads;
|
||||
|
||||
if ( state.userCommentsBeforeReply ) {
|
||||
highlight(
|
||||
pageComments.filter( function ( comment ) {
|
||||
// TODO: Find anon comments?
|
||||
return comment.author === mw.user.getName();
|
||||
} )[ state.userCommentsBeforeReply ]
|
||||
);
|
||||
state.userCommentsBeforeReply = null;
|
||||
}
|
||||
|
||||
parsoidPromise = mw.loader.using( 'ext.visualEditor.targetLoader' ).then( function () {
|
||||
return mw.libs.ve.targetLoader.requestPageData(
|
||||
'visual', parsoidPageData.pageName, { oldId: parsoidPageData.oldId }
|
||||
|
|
|
@ -13,6 +13,10 @@ mw.dt = {
|
|||
if ( new mw.Uri().query.dtdebug ) {
|
||||
mw.loader.load( 'ext.discussionTools.debug' );
|
||||
} else {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
mw.dt.controller.init( $( '#mw-content-text' ) );
|
||||
mw.hook( 'wikipage.content' ).add( function ( $container ) {
|
||||
// Don't re-run if we already handled this element
|
||||
if ( $container.closest( '.dt-init-done' ).length === 0 ) {
|
||||
mw.dt.controller.init( $container.find( '#mw-content-text' ).addBack( '#mw-content-text' ) );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -11,3 +11,15 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.dt-init-highlight {
|
||||
background: rgba( 255, 204, 51, 0.5 );
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
opacity: 1;
|
||||
transition: opacity 500ms;
|
||||
}
|
||||
|
||||
.dt-init-highlight-fade {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
* @extends OO.ui.Widget
|
||||
* @constructor
|
||||
* @param {Object} comment Parsed comment object
|
||||
* @param {number} userCommentsBeforeReply User comments before this reply
|
||||
* @param {Object} [config] Configuration options
|
||||
*/
|
||||
mw.dt.ui.ReplyWidget = function ( comment, config ) {
|
||||
mw.dt.ui.ReplyWidget = function ( comment, userCommentsBeforeReply, config ) {
|
||||
// Parent constructor
|
||||
mw.dt.ui.ReplyWidget.super.call( this, config );
|
||||
|
||||
this.comment = comment;
|
||||
this.userCommentsBeforeReply = userCommentsBeforeReply;
|
||||
|
||||
this.textWidget = new OO.ui.MultilineTextInputWidget( $.extend( {
|
||||
rows: 3,
|
||||
|
@ -63,7 +65,27 @@ mw.dt.ui.ReplyWidget.prototype.onReplyClick = function () {
|
|||
|
||||
this.comment.parsoidPromise.then( function ( parsoidData ) {
|
||||
return mw.dt.controller.postReply( widget, parsoidData );
|
||||
} ).then( function () {
|
||||
location.reload();
|
||||
} ).then( function ( data ) {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
var $container = $( '#mw-content-text' );
|
||||
|
||||
// Update page state
|
||||
$container.html( data.content );
|
||||
mw.config.set( {
|
||||
wgCurRevisionId: data.newrevid,
|
||||
wgRevisionId: data.newrevid
|
||||
} );
|
||||
mw.config.set( data.jsconfigvars );
|
||||
mw.loader.load( data.modules );
|
||||
// TODO update categories, lastmodified
|
||||
// (see ve.init.mw.DesktopArticleTarget.prototype.replacePageContent)
|
||||
|
||||
// Re-initialize
|
||||
mw.dt.controller.init( $container, {
|
||||
userCommentsBeforeReply: widget.userCommentsBeforeReply
|
||||
} );
|
||||
mw.hook( 'wikipage.content' ).fire( $container );
|
||||
|
||||
// TODO: Tell controller to teardown all previous widgets
|
||||
} );
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue