diff --git a/extension.json b/extension.json index c1246e57c..b4f0039df 100644 --- a/extension.json +++ b/extension.json @@ -363,6 +363,8 @@ "VisualEditor.ParsoidClientFactory", "DiscussionTools.CommentParser", "DiscussionTools.SubscriptionStore", + "TempUserCreator", + "UserFactory", "SkinFactory", "ConfigFactory", "RevisionLookup" @@ -395,6 +397,8 @@ "services": [ "VisualEditor.ParsoidClientFactory", "DiscussionTools.CommentParser", + "TempUserCreator", + "UserFactory", "SkinFactory" ] }, diff --git a/includes/ApiDiscussionToolsEdit.php b/includes/ApiDiscussionToolsEdit.php index df64cf218..e577d3f97 100644 --- a/includes/ApiDiscussionToolsEdit.php +++ b/includes/ApiDiscussionToolsEdit.php @@ -16,6 +16,8 @@ use MediaWiki\Logger\LoggerFactory; use MediaWiki\Request\DerivativeRequest; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Title\Title; +use MediaWiki\User\TempUser\TempUserCreator; +use MediaWiki\User\UserFactory; use SkinFactory; use Wikimedia\ParamValidator\ParamValidator; use Wikimedia\ParamValidator\TypeDef\StringDef; @@ -29,6 +31,8 @@ class ApiDiscussionToolsEdit extends ApiBase { private CommentParser $commentParser; private VisualEditorParsoidClientFactory $parsoidClientFactory; private SubscriptionStore $subscriptionStore; + private TempUserCreator $tempUserCreator; + private UserFactory $userFactory; private SkinFactory $skinFactory; private Config $config; private RevisionLookup $revisionLookup; @@ -39,6 +43,8 @@ class ApiDiscussionToolsEdit extends ApiBase { VisualEditorParsoidClientFactory $parsoidClientFactory, CommentParser $commentParser, SubscriptionStore $subscriptionStore, + TempUserCreator $tempUserCreator, + UserFactory $userFactory, SkinFactory $skinFactory, ConfigFactory $configFactory, RevisionLookup $revisionLookup @@ -47,6 +53,8 @@ class ApiDiscussionToolsEdit extends ApiBase { $this->parsoidClientFactory = $parsoidClientFactory; $this->commentParser = $commentParser; $this->subscriptionStore = $subscriptionStore; + $this->tempUserCreator = $tempUserCreator; + $this->userFactory = $userFactory; $this->skinFactory = $skinFactory; $this->config = $configFactory->makeConfig( 'discussiontools' ); $this->revisionLookup = $revisionLookup; @@ -107,7 +115,7 @@ class ApiDiscussionToolsEdit extends ApiBase { $previewContainer = DOMCompat::getBody( DOMUtils::parseHTML( $previewResultHtml ) ); $previewThreadItemSet = $this->commentParser->parse( $previewContainer, $title->getTitleValue() ); if ( CommentUtils::isSingleCommentSignedBy( - $previewThreadItemSet, $this->getUser()->getName(), $previewContainer + $previewThreadItemSet, $this->getUserForPreview()->getName(), $previewContainer ) ) { $signature = null; } else { diff --git a/includes/ApiDiscussionToolsPreview.php b/includes/ApiDiscussionToolsPreview.php index ac84e9e4e..7f7707b67 100644 --- a/includes/ApiDiscussionToolsPreview.php +++ b/includes/ApiDiscussionToolsPreview.php @@ -8,6 +8,8 @@ use ApiUsageException; use MediaWiki\Extension\VisualEditor\ApiParsoidTrait; use MediaWiki\Extension\VisualEditor\VisualEditorParsoidClientFactory; use MediaWiki\Title\Title; +use MediaWiki\User\TempUser\TempUserCreator; +use MediaWiki\User\UserFactory; use SkinFactory; use Wikimedia\ParamValidator\ParamValidator; use Wikimedia\Parsoid\Utils\DOMCompat; @@ -19,6 +21,8 @@ class ApiDiscussionToolsPreview extends ApiBase { private CommentParser $commentParser; private VisualEditorParsoidClientFactory $parsoidClientFactory; + private TempUserCreator $tempUserCreator; + private UserFactory $userFactory; private SkinFactory $skinFactory; public function __construct( @@ -26,11 +30,15 @@ class ApiDiscussionToolsPreview extends ApiBase { string $name, VisualEditorParsoidClientFactory $parsoidClientFactory, CommentParser $commentParser, + TempUserCreator $tempUserCreator, + UserFactory $userFactory, SkinFactory $skinFactory ) { parent::__construct( $main, $name ); $this->parsoidClientFactory = $parsoidClientFactory; $this->commentParser = $commentParser; + $this->tempUserCreator = $tempUserCreator; + $this->userFactory = $userFactory; $this->skinFactory = $skinFactory; } @@ -64,7 +72,9 @@ class ApiDiscussionToolsPreview extends ApiBase { // Check if there was a signature in a proper place $container = DOMCompat::getBody( DOMUtils::parseHTML( $resultHtml ) ); $threadItemSet = $this->commentParser->parse( $container, $title->getTitleValue() ); - if ( !CommentUtils::isSingleCommentSignedBy( $threadItemSet, $this->getUser()->getName(), $container ) ) { + if ( !CommentUtils::isSingleCommentSignedBy( + $threadItemSet, $this->getUserForPreview()->getName(), $container + ) ) { // If not, add the signature and re-render $signature = $this->msg( 'discussiontools-signature-prefix' )->inContentLanguage()->text() . '~~~~'; // Drop opacity of signature in preview to make message body preview clearer. diff --git a/includes/ApiDiscussionToolsTrait.php b/includes/ApiDiscussionToolsTrait.php index 5dc1765d8..8e99d5441 100644 --- a/includes/ApiDiscussionToolsTrait.php +++ b/includes/ApiDiscussionToolsTrait.php @@ -11,6 +11,10 @@ use MediaWiki\Extension\VisualEditor\VisualEditorParsoidClientFactory; use MediaWiki\Request\DerivativeRequest; use MediaWiki\Revision\RevisionRecord; use MediaWiki\Title\Title; +use MediaWiki\User\TempUser\TempUserCreator; +use MediaWiki\User\UserFactory; +use User; +use WebRequest; use Wikimedia\Parsoid\Utils\DOMCompat; use Wikimedia\Parsoid\Utils\DOMUtils; @@ -19,6 +23,8 @@ use Wikimedia\Parsoid\Utils\DOMUtils; * * @property VisualEditorParsoidClientFactory $parsoidClientFactory * @property CommentParser $commentParser + * @property TempUserCreator $tempUserCreator + * @property UserFactory $userFactory */ trait ApiDiscussionToolsTrait { @@ -118,6 +124,20 @@ trait ApiDiscussionToolsTrait { return $api->getResult(); } + /** + * @see ApiParse::getUserForPreview + * @return User + */ + private function getUserForPreview() { + $user = $this->getUser(); + if ( $this->tempUserCreator->shouldAutoCreate( $user, 'edit' ) ) { + return $this->userFactory->newUnsavedTempUser( + $this->tempUserCreator->getStashedName( $this->getRequest()->getSession() ) + ); + } + return $user; + } + /** * @see VisualEditorParsoidClientFactory * @return ParsoidClient @@ -153,4 +173,14 @@ trait ApiDiscussionToolsTrait { */ abstract public function getContext(); + /** + * @return User + */ + abstract public function getUser(); + + /** + * @return WebRequest + */ + abstract public function getRequest(); + } diff --git a/modules/dt.ui.ReplyWidget.js b/modules/dt.ui.ReplyWidget.js index 05b391e52..eaf4fc1f1 100644 --- a/modules/dt.ui.ReplyWidget.js +++ b/modules/dt.ui.ReplyWidget.js @@ -799,14 +799,19 @@ ReplyWidget.prototype.preparePreview = function ( wikitext ) { if ( !wikitext ) { parsePromise = $.Deferred().resolve( null ).promise(); } else { - this.previewRequest = parsePromise = controller.getApi().post( { - action: 'discussiontoolspreview', - type: this.isNewTopic ? 'topic' : 'reply', - page: this.pageName, - wikitext: wikitext, - sectiontitle: title, - useskin: mw.config.get( 'skin' ), - mobileformat: OO.ui.isMobile() + // Acquire a temporary user username before previewing, so that signatures and + // user-related magic words display the temp user instead of IP user in the preview. (T331397) + parsePromise = mw.user.acquireTempUserName().then( function () { + widget.previewRequest = controller.getApi().post( { + action: 'discussiontoolspreview', + type: widget.isNewTopic ? 'topic' : 'reply', + page: widget.pageName, + wikitext: wikitext, + sectiontitle: title, + useskin: mw.config.get( 'skin' ), + mobileformat: OO.ui.isMobile() + } ); + return widget.previewRequest; } ); }