mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-27 15:50:29 +00:00
Merge "Acquire a temporary user username before previewing"
This commit is contained in:
commit
4e9baea69a
|
@ -194,6 +194,7 @@
|
|||
"services": [
|
||||
"RevisionLookup",
|
||||
"TempUserCreator",
|
||||
"UserFactory",
|
||||
"UserOptionsLookup",
|
||||
"WatchlistManager",
|
||||
"ContentTransformer",
|
||||
|
|
|
@ -35,10 +35,12 @@ use MediaWiki\Revision\RevisionLookup;
|
|||
use MediaWiki\SpecialPage\SpecialPageFactory;
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\TempUser\TempUserCreator;
|
||||
use MediaWiki\User\UserFactory;
|
||||
use MediaWiki\User\UserOptionsLookup;
|
||||
use MediaWiki\Watchlist\WatchlistManager;
|
||||
use MessageLocalizer;
|
||||
use RequestContext;
|
||||
use User;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use WikitextContent;
|
||||
|
||||
|
@ -48,6 +50,7 @@ class ApiVisualEditor extends ApiBase {
|
|||
|
||||
private RevisionLookup $revisionLookup;
|
||||
private TempUserCreator $tempUserCreator;
|
||||
private UserFactory $userFactory;
|
||||
private UserOptionsLookup $userOptionsLookup;
|
||||
private WatchlistManager $watchlistManager;
|
||||
private ContentTransformer $contentTransformer;
|
||||
|
@ -62,6 +65,7 @@ class ApiVisualEditor extends ApiBase {
|
|||
string $name,
|
||||
RevisionLookup $revisionLookup,
|
||||
TempUserCreator $tempUserCreator,
|
||||
UserFactory $userFactory,
|
||||
UserOptionsLookup $userOptionsLookup,
|
||||
WatchlistManager $watchlistManager,
|
||||
ContentTransformer $contentTransformer,
|
||||
|
@ -77,6 +81,7 @@ class ApiVisualEditor extends ApiBase {
|
|||
$this->setStats( $statsdDataFactory );
|
||||
$this->revisionLookup = $revisionLookup;
|
||||
$this->tempUserCreator = $tempUserCreator;
|
||||
$this->userFactory = $userFactory;
|
||||
$this->userOptionsLookup = $userOptionsLookup;
|
||||
$this->watchlistManager = $watchlistManager;
|
||||
$this->contentTransformer = $contentTransformer;
|
||||
|
@ -96,6 +101,20 @@ class ApiVisualEditor extends ApiBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run wikitext through the parser's Pre-Save-Transform
|
||||
*
|
||||
|
@ -108,7 +127,7 @@ class ApiVisualEditor extends ApiBase {
|
|||
return $this->contentTransformer->preSaveTransform(
|
||||
$content,
|
||||
$title,
|
||||
$this->getUser(),
|
||||
$this->getUserForPreview(),
|
||||
$this->wikiPageFactory->newFromTitle( $title )->makeParserOptions( $this->getContext() )
|
||||
)
|
||||
->serialize( 'text/x-wiki' );
|
||||
|
|
|
@ -106,45 +106,62 @@ ve.ce.MWSignatureNode.prototype.onTeardown = function () {
|
|||
* @inheritdoc ve.ce.GeneratedContentNode
|
||||
*/
|
||||
ve.ce.MWSignatureNode.prototype.generateContents = function () {
|
||||
// Parsoid doesn't support pre-save transforms. PHP parser doesn't support Parsoid's
|
||||
// meta attributes (that may or may not be required).
|
||||
|
||||
// We could try hacking up one (or even both) of these, but just calling the two parsers
|
||||
// in order seems slightly saner.
|
||||
|
||||
// We must have only one top-level node, this is the easiest way.
|
||||
var wikitext = '<span>~~~~</span>';
|
||||
var doc = this.getModel().getDocument();
|
||||
var abortable, aborted;
|
||||
var abortedPromise = ve.createDeferred().reject( 'http',
|
||||
{ textStatus: 'abort', exception: 'abort' } ).promise();
|
||||
|
||||
var deferred = ve.createDeferred();
|
||||
var xhr = ve.init.target.getContentApi( doc ).post( {
|
||||
action: 'parse',
|
||||
text: wikitext,
|
||||
contentmodel: 'wikitext',
|
||||
prop: 'text',
|
||||
onlypst: true
|
||||
} )
|
||||
.done( function ( resp ) {
|
||||
var wt = ve.getProp( resp, 'parse', 'text' );
|
||||
if ( wt ) {
|
||||
ve.init.target.parseWikitextFragment( wt, true, doc ).then( function ( response ) {
|
||||
if ( ve.getProp( response, 'visualeditor', 'result' ) !== 'success' ) {
|
||||
deferred.reject();
|
||||
return;
|
||||
}
|
||||
function abort() {
|
||||
aborted = true;
|
||||
if ( abortable && abortable.abort ) {
|
||||
abortable.abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Simplified case of template rendering, don't need to worry about filtering etc
|
||||
deferred.resolve( $( response.visualeditor.content ).contents().toArray() );
|
||||
} );
|
||||
} else {
|
||||
deferred.reject();
|
||||
// Acquire a temporary user username before previewing, so that signatures
|
||||
// display the temp user instead of IP user. (T331397)
|
||||
return mw.user.acquireTempUserName()
|
||||
.then( function () {
|
||||
if ( aborted ) {
|
||||
return abortedPromise;
|
||||
}
|
||||
} )
|
||||
.fail( function () {
|
||||
deferred.reject();
|
||||
} );
|
||||
|
||||
return deferred.promise( { abort: xhr.abort } );
|
||||
// We must have only one top-level node, this is the easiest way.
|
||||
var wikitext = '<span>~~~~</span>';
|
||||
|
||||
// Parsoid doesn't support pre-save transforms. PHP parser doesn't support Parsoid's
|
||||
// meta attributes (that may or may not be required).
|
||||
// We could try hacking up one (or even both) of these, but just calling the two parsers
|
||||
// in order seems slightly saner.
|
||||
return ( abortable = ve.init.target.getContentApi( doc ).post( {
|
||||
action: 'parse',
|
||||
text: wikitext,
|
||||
contentmodel: 'wikitext',
|
||||
prop: 'text',
|
||||
onlypst: true
|
||||
} ) );
|
||||
} )
|
||||
.then( function ( pstResponse ) {
|
||||
if ( aborted ) {
|
||||
return abortedPromise;
|
||||
}
|
||||
var wikitext = ve.getProp( pstResponse, 'parse', 'text' );
|
||||
if ( !wikitext ) {
|
||||
return ve.createDeferred().reject();
|
||||
}
|
||||
return ( abortable = ve.init.target.parseWikitextFragment( wikitext, true, doc ) );
|
||||
} )
|
||||
.then( function ( parseResponse ) {
|
||||
if ( aborted ) {
|
||||
return abortedPromise;
|
||||
}
|
||||
if ( ve.getProp( parseResponse, 'visualeditor', 'result' ) !== 'success' ) {
|
||||
return ve.createDeferred().reject();
|
||||
}
|
||||
// Simplified case of template rendering, don't need to worry about filtering etc
|
||||
return $( parseResponse.visualeditor.content ).contents().toArray();
|
||||
} )
|
||||
.promise( { abort: abort } );
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
|
|
@ -915,14 +915,18 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogReview = function () {
|
|||
if ( !this.saveDialog.hasDiff ) {
|
||||
this.emit( 'saveReview' );
|
||||
this.saveDialog.pushPending();
|
||||
if ( this.pageExists ) {
|
||||
// Has no callback, handled via target.showChangesDiff
|
||||
this.showChanges( this.getDocToSave() );
|
||||
} else {
|
||||
this.serialize( this.getDocToSave() ).then( function ( data ) {
|
||||
target.onSaveDialogReviewComplete( data.content );
|
||||
} );
|
||||
}
|
||||
// Acquire a temporary user username before diffing, so that signatures and
|
||||
// user-related magic words display the temp user instead of IP user in the diff. (T331397)
|
||||
mw.user.acquireTempUserName().then( function () {
|
||||
if ( target.pageExists ) {
|
||||
// Has no callback, handled via target.showChangesDiff
|
||||
target.showChanges( target.getDocToSave() );
|
||||
} else {
|
||||
target.serialize( target.getDocToSave() ).then( function ( data ) {
|
||||
target.onSaveDialogReviewComplete( data.content );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
this.saveDialog.swapPanel( 'review' );
|
||||
}
|
||||
|
@ -952,19 +956,23 @@ ve.init.mw.ArticleTarget.prototype.onSaveDialogPreview = function () {
|
|||
params.variant = mw.config.get( 'wgUserVariant' );
|
||||
}
|
||||
|
||||
api.post( ve.extendObject( params, {
|
||||
action: 'parse',
|
||||
title: this.getPageName(),
|
||||
text: this.getDocToSave(),
|
||||
pst: true,
|
||||
preview: true,
|
||||
sectionpreview: this.section !== null,
|
||||
disableeditsection: true,
|
||||
uselang: mw.config.get( 'wgUserLanguage' ),
|
||||
useskin: mw.config.get( 'skin' ),
|
||||
mobileformat: OO.ui.isMobile(),
|
||||
prop: [ 'text', 'categorieshtml', 'displaytitle', 'subtitle', 'modules', 'jsconfigvars' ]
|
||||
} ) ).then( function ( response ) {
|
||||
// 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)
|
||||
mw.user.acquireTempUserName().then( function () {
|
||||
return api.post( ve.extendObject( params, {
|
||||
action: 'parse',
|
||||
title: target.getPageName(),
|
||||
text: target.getDocToSave(),
|
||||
pst: true,
|
||||
preview: true,
|
||||
sectionpreview: target.section !== null,
|
||||
disableeditsection: true,
|
||||
uselang: mw.config.get( 'wgUserLanguage' ),
|
||||
useskin: mw.config.get( 'skin' ),
|
||||
mobileformat: OO.ui.isMobile(),
|
||||
prop: [ 'text', 'categorieshtml', 'displaytitle', 'subtitle', 'modules', 'jsconfigvars' ]
|
||||
} ) );
|
||||
} ).then( function ( response ) {
|
||||
target.saveDialog.showPreview( response );
|
||||
}, function ( errorCode, details ) {
|
||||
target.saveDialog.showPreview( target.extractErrorMessages( details ) );
|
||||
|
@ -1035,14 +1043,18 @@ ve.init.mw.ArticleTarget.prototype.getVisualDiffGeneratorPromise = function () {
|
|||
}
|
||||
|
||||
if ( mode === 'source' ) {
|
||||
var newRevPromise = target.getContentApi().post( {
|
||||
action: 'visualeditor',
|
||||
paction: 'parse',
|
||||
page: target.getPageName(),
|
||||
wikitext: target.getSurface().getDom(),
|
||||
section: target.section,
|
||||
stash: 0,
|
||||
pst: true
|
||||
// Acquire a temporary user username before diffing, so that signatures and
|
||||
// user-related magic words display the temp user instead of IP user in the diff. (T331397)
|
||||
var newRevPromise = mw.user.acquireTempUserName().then( function () {
|
||||
return target.getContentApi().post( {
|
||||
action: 'visualeditor',
|
||||
paction: 'parse',
|
||||
page: target.getPageName(),
|
||||
wikitext: target.getSurface().getDom(),
|
||||
section: target.section,
|
||||
stash: 0,
|
||||
pst: true
|
||||
} );
|
||||
} ).then( function ( response ) {
|
||||
// Source mode always fetches the whole document, so set section=null to unwrap sections
|
||||
return mw.libs.ve.diffLoader.getModelFromResponse( response, null );
|
||||
|
|
|
@ -615,13 +615,41 @@ ve.init.mw.Target.prototype.getWikitextFragment = function ( doc, useRevision )
|
|||
* @return {jQuery.Promise} Abortable promise
|
||||
*/
|
||||
ve.init.mw.Target.prototype.parseWikitextFragment = function ( wikitext, pst, doc ) {
|
||||
return this.getContentApi( doc ).post( {
|
||||
action: 'visualeditor',
|
||||
paction: 'parsefragment',
|
||||
page: this.getPageName( doc ),
|
||||
wikitext: wikitext,
|
||||
pst: pst
|
||||
} );
|
||||
var target = this;
|
||||
var abortable, aborted;
|
||||
var abortedPromise = ve.createDeferred().reject( 'http',
|
||||
{ textStatus: 'abort', exception: 'abort' } ).promise();
|
||||
|
||||
function abort() {
|
||||
aborted = true;
|
||||
if ( abortable && abortable.abort ) {
|
||||
abortable.abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire a temporary user username before previewing or diffing, so that signatures and
|
||||
// user-related magic words display the temp user instead of IP user in the preview. (T331397)
|
||||
var tempUserNamePromise;
|
||||
if ( pst ) {
|
||||
tempUserNamePromise = mw.user.acquireTempUserName();
|
||||
} else {
|
||||
tempUserNamePromise = ve.createDeferred().resolve( null );
|
||||
}
|
||||
|
||||
return tempUserNamePromise
|
||||
.then( function () {
|
||||
if ( aborted ) {
|
||||
return abortedPromise;
|
||||
}
|
||||
return ( abortable = target.getContentApi( doc ).post( {
|
||||
action: 'visualeditor',
|
||||
paction: 'parsefragment',
|
||||
page: target.getPageName( doc ),
|
||||
wikitext: wikitext,
|
||||
pst: pst
|
||||
} ) );
|
||||
} )
|
||||
.promise( { abort: abort } );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue