Wrap up the plain textbox in a ReplyWidget

Depends-On: I765d657c172d96c3b2e2ae5998083e4926a31f15
Change-Id: I3c71fc014b723b0762e2c2be2e0295c57ecfb40d
This commit is contained in:
Ed Sanders 2019-11-05 14:07:50 +00:00
parent cf32465832
commit 41676098fa
3 changed files with 115 additions and 34 deletions

View file

@ -60,6 +60,19 @@
"dependencies": [ "dependencies": [
"ext.discussionTools.parser" "ext.discussionTools.parser"
] ]
},
"ext.discussionTools.ReplyWidget": {
"scripts": [
"dt.ui.ReplyWidget.js"
],
"messages": [],
"dependencies": [
"ext.visualEditor.mwcore",
"ext.visualEditor.mwwikitext",
"ext.visualEditor.core.desktop",
"ext.visualEditor.desktopTarget",
"ext.visualEditor.mwextensions.desktop"
]
} }
}, },
"QUnitTestModule": { "QUnitTestModule": {

View file

@ -1,5 +1,5 @@
var pageComments, pageThreads, parsoidPromise, parsoidComments, parsoidDoc, var pageComments, pageThreads, parsoidPromise, parsoidComments, parsoidDoc,
widgetPromise = mw.loader.using( 'oojs-ui-core' ); replyWidgetPromise = mw.loader.using( 'ext.discussionTools.ReplyWidget' );
/** /**
* @class mw.discussionTools * @class mw.discussionTools
@ -22,6 +22,7 @@ function setupComment( comment ) {
$tsNode.after( $tsNode.after(
' ', ' ',
// TODO: i18n
$( '<a>' ).text( 'Reply' ).on( 'click', function () { $( '<a>' ).text( 'Reply' ).on( 'click', function () {
var newList, newListItem, var newList, newListItem,
$link = $( this ); $link = $( this );
@ -30,43 +31,26 @@ function setupComment( comment ) {
newList = mw.dt.modifier.addListAtComment( comment ); newList = mw.dt.modifier.addListAtComment( comment );
newListItem = mw.dt.modifier.addListItem( newList ); newListItem = mw.dt.modifier.addListItem( newList );
// TODO: i18n
$( newListItem ).text( 'Loading...' ); $( newListItem ).text( 'Loading...' );
widgetPromise.then( function () { replyWidgetPromise.then( function () {
var replyWidget = new OO.ui.MultilineTextInputWidget( { var replyWidget = new mw.dt.ui.ReplyWidget(
value: 'Reply to ' + comment.author comment,
} ), parsoidDoc,
replyButton = new OO.ui.ButtonWidget( { {
flags: [ 'primary', 'progressive' ], // TODO: Remove placeholder
label: 'Reply' doc: '<p>Reply to ' + comment.author + '</p>',
} ); defaultMode: 'source'
replyButton.on( 'click', function () {
comment.parsoidCommentPromise.then( function ( parsoidComment ) {
var html,
newParsoidList = mw.dt.modifier.addListAtComment( parsoidComment );
replyWidget.getValue().split( '\n' ).forEach( function ( line, i, arr ) {
var lineItem = mw.dt.modifier.addListItem( newParsoidList );
if ( i === arr.length - 1 && line.trim().slice( -4 ) !== '~~~~' ) {
line += ' ~~~~';
} }
lineItem.appendChild( mw.dt.modifier.createWikitextNode( line ) ); );
replyWidget.on( 'cancel', function () {
$link.show();
replyWidget.$element.hide();
} ); } );
// TODO: We need an ArticleTargetSaver that is separate from $( newListItem ).empty().append( replyWidget.$element );
// Target logic.
html = ve.init.mw.Target.prototype.getHtml(
parsoidComment.range.endContainer.ownerDocument
);
// eslint-disable-next-line
console.log( html );
} );
} );
$( newListItem ).empty().append(
replyWidget.$element, replyButton.$element
);
replyWidget.focus(); replyWidget.focus();
} ); } );
} ) } )
@ -102,8 +86,9 @@ if ( new mw.Uri().query.dtdebug ) {
oldId: mw.config.get( 'wgRevisionId' ) oldId: mw.config.get( 'wgRevisionId' )
} }
).then( function ( response ) { ).then( function ( response ) {
var data = response.visualeditor;
// TODO: error handling // TODO: error handling
parsoidDoc = ve.createDocumentFromHtml( response.visualeditor.content ); parsoidDoc = ve.createDocumentFromHtml( data.content );
parsoidComments = mw.dt.parser.getComments( parsoidDoc.body ); parsoidComments = mw.dt.parser.getComments( parsoidDoc.body );
// getThreads build the tree structure, currently only // getThreads build the tree structure, currently only

View file

@ -0,0 +1,83 @@
/**
* DiscussionTools ReplyWidget class
*
* @class
* @extends OO.ui.Widget
* @constructor
* @param {Object} comment Parsed comment object
* @param {HTMLDocument} parsoidDoc Parsoid document
* @param {Object} [config] Configuration options
*/
mw.dt.ui.ReplyWidget = function ( comment, parsoidDoc, config ) {
// Parent constructor
mw.dt.ui.ReplyWidget.super.call( this, config );
this.comment = comment;
this.parsoidDoc = parsoidDoc;
this.textWidget = new OO.ui.MultilineTextInputWidget( config );
this.replyButton = new OO.ui.ButtonWidget( {
flags: [ 'primary', 'progressive' ],
label: 'Reply'
} );
this.cancelButton = new OO.ui.ButtonWidget( {
flags: [ 'destructive' ],
label: 'Cancel'
} );
// Events
this.replyButton.connect( this, { click: 'onReplyClick' } );
this.cancelButton.connect( this, { click: [ 'emit', 'cancel' ] } );
this.$element.on( 'keydown', this.onKeyDown.bind( this ) );
// Initialization
this.$element.addClass( 'dt-ui-replyWidget' ).append(
this.textWidget.$element,
$( '<div>' ).addClass( 'dt-ui-replyWidget-actions' ).append(
this.cancelButton.$element,
this.replyButton.$element
)
);
};
/* Inheritance */
OO.inheritClass( mw.dt.ui.ReplyWidget, OO.ui.Widget );
/* Methods */
mw.dt.ui.ReplyWidget.prototype.focus = function () {
this.textWidget.focus();
};
mw.dt.ui.ReplyWidget.prototype.onKeyDown = function ( e ) {
if ( e.which === OO.ui.Keys.ESCAPE ) {
this.emit( 'cancel' );
return false;
}
};
mw.dt.ui.ReplyWidget.prototype.onReplyClick = function () {
var widget = this;
this.comment.parsoidCommentPromise.then( function ( parsoidComment ) {
var html,
newParsoidList = mw.dt.modifier.addListAtComment( parsoidComment );
widget.textWidget.getValue().split( '\n' ).forEach( function ( line, i, arr ) {
var lineItem = mw.dt.modifier.addListItem( newParsoidList );
if ( i === arr.length - 1 && line.trim().slice( -4 ) !== '~~~~' ) {
line += ' ~~~~';
}
lineItem.appendChild( mw.dt.modifier.createWikitextNode( line ) );
} );
// TODO: We need an ArticleTargetSaver that is separate from
// Target logic.
html = ve.init.mw.Target.prototype.getHtml(
parsoidComment.range.endContainer.ownerDocument
);
// eslint-disable-next-line
console.log( html );
} );
};