Alex Monk has uploaded a new change for review.
https://gerrit.wikimedia.org/r/323357
Change subject: [WIP] Undo support
......................................................................
[WIP] Undo support
TODO:
* Inline VE API TODOs
* Check revision deletion? (see EditPage) - may already effectively be handled
* Check content models (see EditPage) - possibly OK to revert non-wikitext
change, as long as *resulting* revision is wikitext?
* nochange case where newContent=oldContent? probably need to set
fromEditedState on the server (see EditPage)
* Auto-summary (see EditPage)
* Open save dialog in review mode
Bug: T78550
Change-Id: Ic8b13b6bb129a46934c5ea31c944e3db78fff828
---
M ApiVisualEditor.php
M VisualEditor.hooks.php
M modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
M modules/ve-mw/init/ve.init.mw.ArticleTarget.js
M modules/ve-mw/init/ve.init.mw.ArticleTargetLoader.js
5 files changed, 77 insertions(+), 24 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/57/323357/1
diff --git a/ApiVisualEditor.php b/ApiVisualEditor.php
index 0ff5f49..30c20c7 100644
--- a/ApiVisualEditor.php
+++ b/ApiVisualEditor.php
@@ -219,20 +219,32 @@
$baseTimestamp =
$latestRevision->getTimestamp();
$oldid = intval( $parserParams['oldid']
);
+ $fetchRevs = [ $oldid ];
+
+ $undo = intval( $params['undo'] );
+ $undoafter = intval(
$params['undoafter'] );
+ if ( $undo > 0 && $undoafter > 0 ) {
+ // TODO: current rev rather
than oldid here? below too
+ $fetchRevs = array_values(
array_unique( [ $oldid, $undo, $undoafter ] ) );
+ }
+ $revContents = [];
+
// If requested, request HTML from
Parsoid/RESTBase
if ( $params['paction'] === 'parse' ) {
- $content =
$this->requestRestbase(
- 'GET',
- 'page/html/' .
urlencode( $title->getPrefixedDBkey() ) . '/' . $oldid . '?redirect=false',
- []
- );
- if ( $content === false ) {
- $this->dieUsage( 'Error
contacting the document server', 'docserver' );
+ foreach ( $fetchRevs as $rev ) {
+ $revContents[$rev] =
$this->requestRestbase(
+ 'GET',
+ 'page/html/' .
urlencode( $title->getPrefixedDBkey() ) . '/' . $rev . '?redirect=false',
+ []
+ );
+ if ( $revContents[$rev]
=== false ) {
+
$this->dieUsage( 'Error contacting the document server to fetch revision ' .
$rev, 'docserver' );
+ }
}
} elseif ( $params['paction'] ===
'wikitext' ) {
$apiParams = [
'action' => 'query',
- 'revids' => $oldid,
+ 'revids' => implode(
'|', $fetchRevs ),
'prop' => 'revisions',
'rvprop' =>
'content|ids'
];
@@ -252,19 +264,45 @@
$api->execute();
$result =
$api->getResult()->getResultData();
$pid = $title->getArticleID();
- $content = false;
+ foreach ( $fetchRevs as $rev ) {
+ $revContents[$rev] =
false;
+ }
if ( isset(
$result['query']['pages'][$pid]['revisions'] ) ) {
foreach (
$result['query']['pages'][$pid]['revisions'] as $revArr ) {
- if (
$revArr['revid'] === $oldid ) {
-
$content = $revArr['content'];
- }
+
$revContents[$revArr['revid']] = $revArr['content'];
}
}
- if ( $content === false ) {
- $this->dieUsage( 'Error
contacting the document server', 'docserver' );
+ foreach ( $fetchRevs as
$checkRev ) {
+ if (
$revContents[$checkRev] === false ) {
+
$this->dieUsage( 'Error contacting the document server to fetch revision ' .
$checkRev, 'docserver' );
+ }
}
}
+ if ( in_array( $params['paction'],
['parse', 'wikitext'] ) ) {
+ if ( $undo > 0 && $undoafter >
0 ) {
+ // merge
+ if (
$revContents[$oldid] == $revContents[$undo] ) {
+ $content =
$revContents[$undoafter];
+ } else {
+ $ok = wfMerge(
+
$revContents[$undo],
+
$revContents[$undoafter],
+
$revContents[$oldid],
+ $result
+ );
+
+ if ( !$ok ) {
+ //
TODO: error
+
wfDebugLog( 'debug', '297' );
+ }
+
+ $content =
$result;
+ }
+ } else {
+ $content =
$revContents[$oldid];
+ }
+ }
} else {
$content = '';
Hooks::run( 'EditFormPreloadText', [
&$content, &$title ] );
@@ -594,6 +632,8 @@
'section' => null,
'oldid' => null,
'pst' => false,
+ 'undo' => null,
+ 'undoafter' => null
];
}
diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php
index 332bcc2..b72ae12 100644
--- a/VisualEditor.hooks.php
+++ b/VisualEditor.hooks.php
@@ -150,8 +150,6 @@
!ApiVisualEditor::isAllowedContentType( $veConfig,
$title->getContentModel() ) ||
// Known parameters that VE does not handle
// TODO: Other params too? See identical list in
ve.init.mw.DesktopArticleTarget.init.js
- isset( $params['undo'] ) ||
- isset( $params['undoafter'] ) ||
isset( $params['editintro'] ) ||
isset( $params['preload'] ) ||
isset( $params['preloadtitle'] ) ||
diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
index 64a1ccf..19d7d02 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
@@ -813,8 +813,6 @@
if ( init.isAvailable ) {
// Load the editor …
if (
- uri.query.undo === undefined &&
- uri.query.undoafter === undefined &&
uri.query.editintro === undefined &&
uri.query.preload === undefined &&
uri.query.preloadtitle === undefined &&
diff --git a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js
b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js
index 4ac09f4..cd0e0af 100644
--- a/modules/ve-mw/init/ve.init.mw.ArticleTarget.js
+++ b/modules/ve-mw/init/ve.init.mw.ArticleTarget.js
@@ -275,7 +275,10 @@
docRevId = parseInt( docRevIdMatches[ 1 ] );
}
}
- if ( docRevId && docRevId !== this.revid ) {
+ // We check fromEditedState here because when we're undoing a
revision,
+ // we're going to expect to be editing a revision different
from the
+ // current one and the easiest way to check this is
fromEditedState.
+ if ( docRevId && docRevId !== this.revid &&
!this.fromEditedState ) {
if ( this.retriedRevIdConflict ) {
// Retried already, just error the second time.
this.loadFail(
diff --git a/modules/ve-mw/init/ve.init.mw.ArticleTargetLoader.js
b/modules/ve-mw/init/ve.init.mw.ArticleTargetLoader.js
index 8b62bd9..d3071cf 100644
--- a/modules/ve-mw/init/ve.init.mw.ArticleTargetLoader.js
+++ b/modules/ve-mw/init/ve.init.mw.ArticleTargetLoader.js
@@ -126,11 +126,18 @@
var start, apiXhr, restbaseXhr, apiPromise,
restbasePromise, dataPromise, pageHtmlUrl, headers,
switched = false,
fromEditedState = false,
+ undoing = (
+ mw.util.getParamValue( 'undo' ) > 0 &&
+ mw.util.getParamValue( 'undoafter' ) > 0
+ ),
+ canContactRESTBase = ( !undoing && (
conf.fullRestbaseUrl || conf.restbaseUrl ) ),
data = {
action: 'visualeditor',
- paction: ( conf.fullRestbaseUrl ||
conf.restbaseUrl ) ? 'metadata' : 'parse',
+ paction: canContactRESTBase ?
'metadata' : 'parse',
page: pageName,
- uselang: mw.config.get(
'wgUserLanguage' )
+ uselang: mw.config.get(
'wgUserLanguage' ),
+ undo: mw.util.getParamValue( 'undo' ),
+ undoafter: mw.util.getParamValue(
'undoafter' )
};
// Only request the API to explicitly load the
currently visible revision if we're restoring
@@ -156,7 +163,7 @@
return data;
} );
- if ( conf.fullRestbaseUrl || conf.restbaseUrl ) {
+ if ( canContactRESTBase ) {
ve.track( 'trace.restbaseLoad.enter' );
// Should be synchronised with
ApiVisualEditor.php
@@ -238,7 +245,12 @@
restbaseXhr.abort();
} } );
} else {
- dataPromise = apiPromise.promise( { abort:
apiXhr.abort } );
+ dataPromise = apiPromise.then( function ( data
) {
+ if ( data.visualeditor && undoing ) {
+
data.visualeditor.fromEditedState = true;
+ }
+ return data;
+ } ).promise( { abort: apiXhr.abort } );
}
return dataPromise;
@@ -249,7 +261,9 @@
action: 'visualeditor',
paction: 'wikitext',
page: pageName,
- uselang: mw.config.get( 'wgUserLanguage' )
+ uselang: mw.config.get( 'wgUserLanguage' ),
+ undo: mw.util.getParamValue( 'undo' ),
+ undoafter: mw.util.getParamValue( 'undoafter' )
};
// section should never really be undefined, but check
just in case
--
To view, visit https://gerrit.wikimedia.org/r/323357
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic8b13b6bb129a46934c5ea31c944e3db78fff828
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Alex Monk <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits