From 5a792b6558060de5ba8d6bbb231048a37c54a576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= Date: Sat, 3 Jun 2023 03:19:38 +0200 Subject: [PATCH] ApiVisualEditorEdit: Allow not returning the new revision content Sometimes we call this API and then reload the page (or navigate to another URL), without using the page content it returns. Save some work and some data transfer and don't generate it in those cases. Change-Id: Ic5fac61f3ef9b2dfce6ff757f1d414a9f41f217d --- i18n/ve-mw/api/en.json | 1 + i18n/ve-mw/api/qqq.json | 1 + includes/ApiVisualEditorEdit.php | 32 +++++++++++-------- .../init/targets/ve.init.mw.ArticleTarget.js | 10 +++++- .../ve.init.mw.DesktopArticleTarget.js | 3 +- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/i18n/ve-mw/api/en.json b/i18n/ve-mw/api/en.json index 82290dfa59..81b131a5ac 100644 --- a/i18n/ve-mw/api/en.json +++ b/i18n/ve-mw/api/en.json @@ -50,6 +50,7 @@ "apihelp-visualeditoredit-param-cachekey": "Use the result of a previous serializeforcache request with this key. Overrides $1html.", "apihelp-visualeditoredit-param-captchaid": "Captcha ID (when saving with a captcha response).", "apihelp-visualeditoredit-param-captchaword": "Answer to the captcha (when saving with a captcha response).", + "apihelp-visualeditoredit-param-nocontent": "Omit the HTML content of the new revision in the response.", "apihelp-visualeditoredit-param-plugins": "Plugins associated with the API request.", "apihelp-visualeditoredit-param-data-{plugin}": "Arbitrary data sent by a plugin with the API request.", "apihelp-visualeditoredit-param-etag": "ETag to send.", diff --git a/i18n/ve-mw/api/qqq.json b/i18n/ve-mw/api/qqq.json index 6efb70a8b9..36c371ce07 100644 --- a/i18n/ve-mw/api/qqq.json +++ b/i18n/ve-mw/api/qqq.json @@ -59,6 +59,7 @@ "apihelp-visualeditoredit-param-cachekey": "{{doc-apihelp-param|visualeditoredit|cachekey}}", "apihelp-visualeditoredit-param-captchaid": "{{doc-apihelp-param|visualeditoredit|captchaid}}", "apihelp-visualeditoredit-param-captchaword": "{{doc-apihelp-param|visualeditoredit|captchaword}}", + "apihelp-visualeditoredit-param-nocontent": "{{doc-apihelp-param|visualeditoredit|nocontent}}", "apihelp-visualeditoredit-param-plugins": "{{doc-apihelp-param|visualeditoredit|plugins}}", "apihelp-visualeditoredit-param-data-{plugin}": "{{doc-apihelp-param|visualeditoredit|data-{plugin} }}", "apihelp-visualeditoredit-param-etag": "{{doc-apihelp-param|visualeditoredit|etag}}", diff --git a/includes/ApiVisualEditorEdit.php b/includes/ApiVisualEditorEdit.php index 4a953a4de1..433cbf311a 100644 --- a/includes/ApiVisualEditorEdit.php +++ b/includes/ApiVisualEditorEdit.php @@ -21,6 +21,7 @@ use DifferenceEngine; use ExtensionRegistry; use FlaggablePageView; use IBufferingStatsdDataFactory; +use IDBAccessObject; use MediaWiki\Logger\LoggerFactory; use MediaWiki\Page\WikiPageFactory; use MediaWiki\Storage\PageEditStash; @@ -442,18 +443,23 @@ class ApiVisualEditorEdit extends ApiBase { } else { // Success $result['result'] = 'success'; - if ( isset( $saveresult['edit']['newrevid'] ) ) { - $newRevId = intval( $saveresult['edit']['newrevid'] ); + + if ( $params['nocontent'] ) { + $result['nocontent'] = true; } else { - $newRevId = $title->getLatestRevID(); + if ( isset( $saveresult['edit']['newrevid'] ) ) { + $newRevId = intval( $saveresult['edit']['newrevid'] ); + } else { + $newRevId = $title->getLatestRevID(); + } + + // Return result of parseWikitext instead of saveWikitext so that the + // frontend can update the page rendering without a refresh. + $parseWikitextResult = $this->parseWikitext( $newRevId, $params ); + + $result = array_merge( $result, $parseWikitextResult ); } - // Return result of parseWikitext instead of saveWikitext so that the - // frontend can update the page rendering without a refresh. - $parseWikitextResult = $this->parseWikitext( $newRevId, $params ); - - $result = array_merge( $result, $parseWikitextResult ); - $result['isRedirect'] = (string)$title->isRedirect(); if ( ExtensionRegistry::getInstance()->isLoaded( 'FlaggedRevs' ) ) { @@ -508,11 +514,8 @@ class ApiVisualEditorEdit extends ApiBase { } $this->hookRunner->onVisualEditorApiVisualEditorEditPostSave( - // The earlier call to $title->toPageIdentity() will have an article ID of 0 for new article - // creation. Because of title cache (Title::$titleCache), $title->getId() will change value during the - // parseWikitext() call in that case, but the ID of a PageIdentityValue object won't, so we need to create - // a new one here. - $title->toPageIdentity(), + // Refresh data (like article ID) in case we just created the page + $title->toPageRecord( IDBAccessObject::READ_LATEST ), $user, $wikitext, $params, @@ -577,6 +580,7 @@ class ApiVisualEditorEdit extends ApiBase { 'captchaid' => null, 'captchaword' => null, 'cachekey' => null, + 'nocontent' => false, 'useskin' => [ ParamValidator::PARAM_TYPE => array_keys( $this->skinFactory->getInstalledSkins() ), ApiBase::PARAM_HELP_MSG => 'apihelp-parse-param-useskin', diff --git a/modules/ve-mw/init/targets/ve.init.mw.ArticleTarget.js b/modules/ve-mw/init/targets/ve.init.mw.ArticleTarget.js index c5c1eae29c..297dbfa331 100644 --- a/modules/ve-mw/init/targets/ve.init.mw.ArticleTarget.js +++ b/modules/ve-mw/init/targets/ve.init.mw.ArticleTarget.js @@ -615,6 +615,7 @@ ve.init.mw.ArticleTarget.prototype.replacePageContent = function ( * Handle successful DOM save event. * * @param {Object} data Save data from the API + * @param {boolean} data.nocontent Indicates that page HTML and related properties were omitted * @param {string} data.content Rendered page HTML from server * @param {string} data.categorieshtml Rendered categories HTML from server * @param {number} data.newrevid New revision id, undefined if unchanged @@ -638,7 +639,7 @@ ve.init.mw.ArticleTarget.prototype.saveComplete = function ( data ) { var target = this; // This is a page creation, a restoration, or we loaded the editor from a non-view page: refresh the page. - if ( !this.pageExists || this.restoring || !this.isViewPage ) { + if ( data.nocontent ) { // Teardown the target, ensuring auto-save data is cleared this.teardown().then( function () { var newUrl = new URL( target.viewUrl ); @@ -1523,6 +1524,13 @@ ve.init.mw.ArticleTarget.prototype.save = function ( doc, options, isRetry ) { assertuser: mw.user.getName() || undefined } ); + if ( !this.pageExists || this.restoring || !this.isViewPage ) { + // This is a page creation, a restoration, or we loaded the editor from a non-view page. + // We can't update the interface to reflect this new state, so we're going to reload the whole page. + // Therefore we don't need the new revision's HTML content in the API response. + data.nocontent = true; + } + var config = mw.config.get( 'wgVisualEditorConfig' ); var taglist = data.vetags ? data.vetags.split( ',' ) : []; diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js index 3655d50701..2e6f7ab72c 100644 --- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js +++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js @@ -855,7 +855,8 @@ ve.init.mw.DesktopArticleTarget.prototype.saveComplete = function ( data ) { // Parent method ve.init.mw.DesktopArticleTarget.super.prototype.saveComplete.apply( this, arguments ); - if ( this.pageExists && !this.restoring ) { + // If there is no content, then parent method will reload the whole page + if ( !data.nocontent ) { // Fix permalinks if ( data.newrevid !== undefined ) { $( '#t-permalink' ).add( '#coll-download-as-rl' ).find( 'a' ).each( function () {