Merge "Create a PingNode so user pings are single focusable nodes"

This commit is contained in:
jenkins-bot 2020-07-20 17:13:32 +00:00 committed by Gerrit Code Review
commit 271124d5cb
5 changed files with 158 additions and 6 deletions

View file

@ -132,7 +132,9 @@
"dt-ve/CommentTarget.js",
"dt-ve/CommentTargetWidget.js",
"dt-ve/dt.ui.UsernameCompletionAction.js",
"dt-ve/dt.ui.UsernameCompletionTool.js"
"dt-ve/dt.ui.UsernameCompletionTool.js",
"dt-ve/dt.dm.PingNode.js",
"dt-ve/dt.ce.PingNode.js"
],
"styles": [
"dt-ve/CommentTargetWidget.less"

View file

@ -0,0 +1,78 @@
/*!
* VisualEditor ContentEditable MWPingNode class.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* @external DmMWPingNode
*/
/**
* ContentEditable MediaWiki ping node.
*
* @class
* @extends ve.ce.LeafNode
* @mixins ve.ce.FocusableNode
*
* @constructor
* @param {DmMWPingNode} model Model to observe
* @param {Object} [config] Configuration options
*/
function CeMWPingNode() {
// Parent constructor
CeMWPingNode.super.apply( this, arguments );
// Mixin constructor
ve.ce.FocusableNode.call( this );
}
/* Inheritance */
OO.inheritClass( CeMWPingNode, ve.ce.LeafNode );
OO.mixinClass( CeMWPingNode, ve.ce.FocusableNode );
/* Static Properties */
CeMWPingNode.static.name = 'mwPing';
CeMWPingNode.static.tagName = 'a';
CeMWPingNode.static.getDescription = function ( model ) {
return model.getAttribute( 'user' );
};
/* Methods */
/**
* @inheritdoc
*/
CeMWPingNode.prototype.initialize = function () {
var model = this.getModel(),
user = model.getAttribute( 'user' ),
title = mw.Title.makeTitle( mw.config.get( 'wgNamespaceIds' ).user, user );
// Parent method
CeMWPingNode.super.prototype.initialize.call( this );
// DOM changes
this.$element
.addClass( 'dt-ce-mwPingNode' )
.attr( {
href: title.getUrl(),
title: user
} )
.text( model.getAttribute( 'user' ) );
ve.init.platform.linkCache.styleElement(
title.getPrefixedText(),
this.$element
);
};
/* Registration */
ve.ce.nodeFactory.register( CeMWPingNode );

View file

@ -0,0 +1,67 @@
/*!
* VisualEditor DataModel MWPingNode class.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* DataModel MediaWiki ping node. A ping is just a link to a user page, but
* by defining it as a node we can make is a single FocusableNode.
*
* @class
* @extends ve.dm.LeafNode
* @mixins ve.dm.FocusableNode
*
* @constructor
* @param {Object} [element] Reference to element in linear model
*/
function DmMWPingNode() {
// Parent constructor
DmMWPingNode.super.apply( this, arguments );
// Mixin constructor
ve.dm.FocusableNode.call( this );
}
/* Inheritance */
OO.inheritClass( DmMWPingNode, ve.dm.LeafNode );
OO.mixinClass( DmMWPingNode, ve.dm.FocusableNode );
/* Static members */
DmMWPingNode.static.name = 'mwPing';
DmMWPingNode.static.isContent = true;
DmMWPingNode.static.matchTagNames = null;
DmMWPingNode.static.matchRdfaTypes = [];
DmMWPingNode.static.matchFunction = function () {
return false;
};
DmMWPingNode.static.disallowedAnnotationTypes = [ 'link' ];
DmMWPingNode.static.toDomElements = function ( dataElement, doc, converter ) {
var domElements,
title = mw.Title.makeTitle( mw.config.get( 'wgNamespaceIds' ).user, dataElement.attributes.user );
dataElement = ve.dm.MWInternalLinkAnnotation.static.dataElementFromTitle( title );
domElements = ve.dm.MWInternalLinkAnnotation.static.toDomElements( dataElement, doc, converter );
domElements[ 0 ].appendChild(
doc.createTextNode( title.getMainText() )
);
return domElements;
};
// toDataElement should never be called for this node
DmMWPingNode.static.toDataElement = null;
/* Registration */
ve.dm.modelRegistry.register( DmMWPingNode );

View file

@ -111,16 +111,19 @@ MWUsernameCompletionAction.prototype.insertCompletion = function ( word, range )
var fragment,
// TODO: Allow output customisation (T250332)
prefix = '@',
title = mw.Title.newFromText( word, mw.config.get( 'wgNamespaceIds' ).user ),
annotation = ve.dm.MWInternalLinkAnnotation.static.newFromTitle( title );
title = mw.Title.newFromText( word, mw.config.get( 'wgNamespaceIds' ).user );
if ( this.surface.getMode() === 'source' ) {
// TODO: this should be configurable per-wiki so that e.g. custom templates can be used
word = prefix + '[[' + title.getPrefixedText() + '|' + word + ']]';
return MWUsernameCompletionAction.super.prototype.insertCompletion.call( this, word, range );
}
fragment = MWUsernameCompletionAction.super.prototype.insertCompletion.apply( this, arguments )
.annotateContent( 'clear', 'link' ).annotateContent( 'clear', 'link/mwInternal' )
.annotateContent( 'set', annotation );
fragment = this.surface.getModel().getLinearFragment( range );
fragment.removeContent().insertContent( [
{ type: 'mwPing', attributes: { user: word } },
{ type: '/mwPing' }
] );
fragment.collapseToStart().insertContent( '@' );

View file

@ -2,6 +2,8 @@ var CommentTargetWidget = require( './dt-ve/CommentTargetWidget.js' );
require( './dt-ve/dt.ui.UsernameCompletionAction.js' );
require( './dt-ve/dt.ui.UsernameCompletionTool.js' );
require( './dt-ve/dt.dm.PingNode.js' );
require( './dt-ve/dt.ce.PingNode.js' );
/**
* DiscussionTools ReplyWidgetVisual class