Edit Recovery: add new special page to list unsaved changes
Add Special:EditRecovery to dispaly a basic list of all pages with locally-saved edit recovery data. This change just sets up the initial work for this, and the actual design and improved UX will come in subsequent changes. Bug: T347673 Change-Id: I8edbfd21258fcb2e4fc9f3e4ded9876d6635d752
This commit is contained in:
parent
86d135301a
commit
fb2f0d003c
11 changed files with 157 additions and 0 deletions
|
|
@ -2053,6 +2053,7 @@ $wgAutoloadLocalClasses = [
|
|||
'MediaWiki\\Specials\\SpecialDiff' => __DIR__ . '/includes/specials/SpecialDiff.php',
|
||||
'MediaWiki\\Specials\\SpecialDoubleRedirects' => __DIR__ . '/includes/specials/SpecialDoubleRedirects.php',
|
||||
'MediaWiki\\Specials\\SpecialEditPage' => __DIR__ . '/includes/specials/SpecialEditPage.php',
|
||||
'MediaWiki\\Specials\\SpecialEditRecovery' => __DIR__ . '/includes/specials/SpecialEditRecovery.php',
|
||||
'MediaWiki\\Specials\\SpecialEditTags' => __DIR__ . '/includes/specials/SpecialEditTags.php',
|
||||
'MediaWiki\\Specials\\SpecialEditWatchlist' => __DIR__ . '/includes/specials/SpecialEditWatchlist.php',
|
||||
'MediaWiki\\Specials\\SpecialEmailInvalidate' => __DIR__ . '/includes/specials/SpecialEmailInvalidate.php',
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ use MediaWiki\Specials\SpecialDeletePage;
|
|||
use MediaWiki\Specials\SpecialDiff;
|
||||
use MediaWiki\Specials\SpecialDoubleRedirects;
|
||||
use MediaWiki\Specials\SpecialEditPage;
|
||||
use MediaWiki\Specials\SpecialEditRecovery;
|
||||
use MediaWiki\Specials\SpecialEditTags;
|
||||
use MediaWiki\Specials\SpecialEditWatchlist;
|
||||
use MediaWiki\Specials\SpecialEmailInvalidate;
|
||||
|
|
@ -1232,6 +1233,7 @@ class SpecialPageFactory {
|
|||
MainConfigNames::EnableEmail,
|
||||
MainConfigNames::EnableJavaScriptTest,
|
||||
MainConfigNames::EnableSpecialMute,
|
||||
MainConfigNames::EnableEditRecovery,
|
||||
MainConfigNames::PageLanguageUseDB,
|
||||
MainConfigNames::SpecialPages,
|
||||
];
|
||||
|
|
@ -1356,6 +1358,12 @@ class SpecialPageFactory {
|
|||
];
|
||||
}
|
||||
|
||||
if ( $this->options->get( MainConfigNames::EnableEditRecovery ) ) {
|
||||
$this->list['EditRecovery'] = [
|
||||
'class' => SpecialEditRecovery::class,
|
||||
];
|
||||
}
|
||||
|
||||
// Add extension special pages
|
||||
$this->list = array_merge( $this->list,
|
||||
$this->options->get( MainConfigNames::SpecialPages ) );
|
||||
|
|
|
|||
41
includes/specials/SpecialEditRecovery.php
Normal file
41
includes/specials/SpecialEditRecovery.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* @ingroup SpecialPage
|
||||
*/
|
||||
|
||||
namespace MediaWiki\Specials;
|
||||
|
||||
use MediaWiki\Html\Html;
|
||||
use MediaWiki\SpecialPage\SpecialPage;
|
||||
|
||||
/**
|
||||
* @ingroup SpecialPage
|
||||
*/
|
||||
class SpecialEditRecovery extends SpecialPage {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct( 'EditRecovery' );
|
||||
}
|
||||
|
||||
protected function getGroupName() {
|
||||
return 'changes';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $subPage
|
||||
*/
|
||||
public function execute( $subPage ) {
|
||||
parent::execute( $subPage );
|
||||
$this->addHelpLink( 'Help:Edit_Recovery' );
|
||||
$this->getOutput()->addModuleStyles( 'mediawiki.special.editrecovery.styles' );
|
||||
$this->getOutput()->addModules( 'mediawiki.special.editrecovery' );
|
||||
$noJs = Html::element(
|
||||
'span',
|
||||
[ 'class' => 'error mw-EditRecovery-special-nojs-notice' ],
|
||||
$this->msg( 'edit-recovery-nojs-placeholder' )
|
||||
);
|
||||
$placeholder = Html::rawElement( 'div', [ 'class' => 'mw-EditRecovery-special' ], $noJs );
|
||||
$this->getOutput()->addHTML( $placeholder );
|
||||
}
|
||||
}
|
||||
|
|
@ -650,6 +650,10 @@
|
|||
"resettokens-done": "Tokens reset.",
|
||||
"resettokens-resetbutton": "Reset selected tokens",
|
||||
"sig-text": "--$1",
|
||||
"editrecovery": "Edit Recovery",
|
||||
"edit-recovery-nojs-placeholder": "JavaScript is required for the Edit Recovery feature.",
|
||||
"edit-recovery-special-intro": "You have unsaved changes to the following {{PLURAL:$1|page or section|pages and/or sections}}:",
|
||||
"edit-recovery-special-intro-empty": "You have no unsaved changes.",
|
||||
"edit-recovery-loaded-title": "Changes recovered",
|
||||
"edit-recovery-loaded-message": "Your unsaved changes have been automatically recovered.",
|
||||
"edit-recovery-loaded-show": "Show changes",
|
||||
|
|
|
|||
|
|
@ -904,6 +904,10 @@
|
|||
"resettokens-done": "Message shown on [[Special:ResetTokens]] after the tokens have been reset successfully.",
|
||||
"resettokens-resetbutton": "Form submit button on [[Special:ResetTokens]].",
|
||||
"sig-text": "{{notranslate}} This is the text that appears when you click on the signature button (second button from the right) on the edit toolbar. $1 will be replaced with four tildes (which cannot be included directly in the message for technical reasons).",
|
||||
"editrecovery": "{{doc-special|EditRecovery}}",
|
||||
"edit-recovery-nojs-placeholder": "Error message shown when JavaScript is disabled.",
|
||||
"edit-recovery-special-intro": "Message shown above a list of linked page titles.\n\nParameters:\n\n* $1 — Integer number of list items.",
|
||||
"edit-recovery-special-intro-empty": "Message shown instead of the list of pages when the list is empty.",
|
||||
"edit-recovery-loaded-title": "Title for a notification toast popup shown when an in-progress edit is recovered.",
|
||||
"edit-recovery-loaded-message": "Message shown in a notification toast popup when an in-progress edit is recovered.",
|
||||
"edit-recovery-loaded-show": "Button text in a notification toast popup shown when an in-progress edit is recovered, used to show changes.",
|
||||
|
|
|
|||
|
|
@ -430,6 +430,7 @@ $specialPageAliases = [
|
|||
'Diff' => [ 'Diff' ],
|
||||
'DoubleRedirects' => [ 'DoubleRedirects' ],
|
||||
'EditPage' => [ 'EditPage', 'Edit' ],
|
||||
'EditRecovery' => [ 'EditRecovery' ],
|
||||
'EditTags' => [ 'EditTags' ],
|
||||
'EditWatchlist' => [ 'EditWatchlist' ],
|
||||
'Emailuser' => [ 'EmailUser', 'Email' ],
|
||||
|
|
|
|||
|
|
@ -2289,6 +2289,25 @@ return [
|
|||
'mediawiki.special.preferences.styles.ooui' => [
|
||||
'styles' => 'resources/src/mediawiki.special.preferences.styles.ooui.less',
|
||||
],
|
||||
'mediawiki.special.editrecovery.styles' => [
|
||||
'styles' => 'resources/src/mediawiki.special.editrecovery/styles.less',
|
||||
],
|
||||
'mediawiki.special.editrecovery' => [
|
||||
'packageFiles' => [
|
||||
'resources/src/mediawiki.special.editrecovery/init.js',
|
||||
'resources/src/mediawiki.special.editrecovery/SpecialEditRecovery.vue',
|
||||
'resources/src/mediawiki.editRecovery/storage.js',
|
||||
],
|
||||
'dependencies' => [
|
||||
'vue',
|
||||
],
|
||||
'messages' => [
|
||||
'editlink',
|
||||
'parentheses',
|
||||
'edit-recovery-special-intro',
|
||||
'edit-recovery-special-intro-empty',
|
||||
],
|
||||
],
|
||||
'mediawiki.special.search' => [
|
||||
'scripts' => 'resources/src/mediawiki.special.search/search.js',
|
||||
'dependencies' => 'mediawiki.widgets.SearchInputWidget',
|
||||
|
|
|
|||
|
|
@ -85,6 +85,21 @@ function loadData( pageName, section ) {
|
|||
} );
|
||||
}
|
||||
|
||||
function loadAllData() {
|
||||
return new Promise( function ( resolve, reject ) {
|
||||
if ( !db ) {
|
||||
reject( 'DB not opened' );
|
||||
}
|
||||
const transaction = db.transaction( objectStoreName, 'readonly' );
|
||||
const requestAll = transaction
|
||||
.objectStore( objectStoreName )
|
||||
.getAll();
|
||||
requestAll.addEventListener( 'success', function () {
|
||||
resolve( requestAll.result );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data for a specific page and section
|
||||
*
|
||||
|
|
@ -213,6 +228,7 @@ module.exports = {
|
|||
openDatabase: openDatabaseLocal,
|
||||
closeDatabase: closeDatabase,
|
||||
loadData: loadData,
|
||||
loadAllData: loadAllData,
|
||||
saveData: saveData,
|
||||
deleteData: deleteData,
|
||||
deleteExpiredData: deleteExpiredData
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<p v-if="pages.length">
|
||||
{{ $i18n( 'edit-recovery-special-intro', pages.length ) }}
|
||||
</p>
|
||||
<p v-else>
|
||||
{{ $i18n( 'edit-recovery-special-intro-empty' ) }}
|
||||
</p>
|
||||
<ul>
|
||||
<li v-for="page in pages" :key="page">
|
||||
<a :href="page.url">{{ page.title }}</a>
|
||||
<span v-if="page.section"> – {{ page.section }}</span>
|
||||
<span>
|
||||
<a :href="page.editUrl">{{ $i18n( 'parentheses', $i18n( 'editlink' ) ) }}</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const { ref } = require( 'vue' );
|
||||
// @vue/component
|
||||
module.exports = {
|
||||
setup() {
|
||||
const pages = ref( [] );
|
||||
const storage = require( '../mediawiki.editRecovery/storage.js' );
|
||||
storage.openDatabase().then( () => {
|
||||
storage.loadAllData().then( ( allData ) => {
|
||||
allData.forEach( ( d ) => {
|
||||
const title = new mw.Title( d.pageName );
|
||||
const editParams = { action: 'edit' };
|
||||
if ( d.section ) {
|
||||
editParams.section = d.section;
|
||||
}
|
||||
pages.value.push( {
|
||||
title: title.getPrefixedText(),
|
||||
url: title.getUrl(),
|
||||
editUrl: title.getUrl( editParams ),
|
||||
section: d.section,
|
||||
sectionLabel: d.section ? mw.msg( 'parentheses', mw.msg( 'search-section', d.section ) ) : ''
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
return {
|
||||
pages
|
||||
};
|
||||
}
|
||||
};
|
||||
// eslint-disable-next-line vue/dot-location
|
||||
</script>
|
||||
10
resources/src/mediawiki.special.editrecovery/init.js
Normal file
10
resources/src/mediawiki.special.editrecovery/init.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
( function () {
|
||||
'use strict';
|
||||
const outer = document.querySelector( '.mw-EditRecovery-special' );
|
||||
if ( !outer ) {
|
||||
return;
|
||||
}
|
||||
const Vue = require( 'vue' );
|
||||
const App = require( './SpecialEditRecovery.vue' );
|
||||
Vue.createMwApp( App ).mount( outer );
|
||||
}() );
|
||||
3
resources/src/mediawiki.special.editrecovery/styles.less
Normal file
3
resources/src/mediawiki.special.editrecovery/styles.less
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.client-js .mw-EditRecovery-special-nojs-notice {
|
||||
display: none;
|
||||
}
|
||||
Loading…
Reference in a new issue