diff --git a/src/modules/core.js b/src/modules/core.js
index 69837ef5..75388685 100644
--- a/src/modules/core.js
+++ b/src/modules/core.js
@@ -996,7 +996,7 @@
/**
* Represents an element in the status container
*
- * @param {string} initialText Initial text of the element
+ * @param {string} initialText Initial text of the element
* @param {Object} substitutions key-value pairs of strings that should be replaced by something
* else. For example, { '$2': mw.user.getUser() }. If not redefined, $1
* will be equal to the current page name.
@@ -1005,7 +1005,7 @@
/**
* Replace the status element with new html content
*
- * @param {jQuery|string} html Content of the element
+ * @param {jQuery|string} html Content of the element
* Can use $1 to represent the page name
*/
this.update = function ( html ) {
@@ -1510,16 +1510,23 @@
* @param {string} pagename - The title of the page.
* @param {string} displayTitle - What gets shown by the link.
* @param {boolean} [newTab=true] - Whether to open page in a new tab.
+ * @param {boolean} dontFollowRedirects - whether to add &redirect=no to URLs, to prevent auto redirecting when clicked
* @return {jQuery} element
*/
- makeLinkElementToPage: function ( pagename, displayTitle, newTab ) {
+ makeLinkElementToPage: function ( pagename, displayTitle, newTab, dontFollowRedirects ) {
var actualTitle = pagename.replace( /_/g, ' ' );
// newTab is an optional parameter.
newTab = ( typeof newTab === 'undefined' ) ? true : newTab;
+ var options = {};
+ if ( dontFollowRedirects ) {
+ options = { redirect: 'no' };
+ }
+ var url = mw.util.getUrl( actualTitle, options );
+
return $( '' )
- .attr( 'href', mw.util.getUrl( actualTitle ) )
+ .attr( 'href', url )
.attr( 'id', 'afch-cat-link-' + pagename.toLowerCase().replace( / /g, '-' ).replace( /\//g, '-' ) )
.attr( 'title', actualTitle )
.text( displayTitle || actualTitle )
diff --git a/src/modules/submissions.js b/src/modules/submissions.js
index 6837b3b1..568d0bc0 100644
--- a/src/modules/submissions.js
+++ b/src/modules/submissions.js
@@ -1301,7 +1301,6 @@
// Handler will run after the main AJAX requests complete
setupAjaxStopHandler();
-
}
/**
@@ -1755,6 +1754,7 @@
$status.text( '' );
$submitButton
.removeClass( 'disabled' )
+ .css( 'pointer-events', 'auto' )
.text( 'Accept & publish' );
// If there is no value, die now, because otherwise mw.Title
@@ -1787,22 +1787,31 @@
inprop: 'protection',
titles: page.rawTitle
} )
- ).then( function ( rawBlacklistResult, rawData ) {
+ ).then( function ( rawBlacklist, rawInfo ) {
var errorHtml, buttonText;
// Get just the result, not the Promise object
- var blacklistResult = rawBlacklistResult[ 0 ],
- data = rawData[ 0 ];
+ var blacklistResult = rawBlacklist[ 0 ],
+ infoResult = rawInfo[ 0 ];
- // If the page already exists, display an error
- if ( !data.query.pages.hasOwnProperty( '-1' ) ) {
+ var pageAlreadyExists = !infoResult.query.pages.hasOwnProperty( '-1' );
+
+ var pages = infoResult && infoResult.query && infoResult.query.pages && infoResult.query.pages;
+ var firstPageInObject = Object.values( pages )[ 0 ];
+ var pageIsRedirect = firstPageInObject && ( 'redirect' in firstPageInObject );
+
+ if ( pageAlreadyExists && pageIsRedirect ) {
+ var linkToRedirect = AFCH.jQueryToHtml( AFCH.makeLinkElementToPage( page.rawTitle, null, null, true ) );
+ errorHtml = '
Whoops, the page "' + linkToRedirect + '" already exists and is a redirect. Do you want to tag it for speedy deletion so you can accept this draft later? Yes / No';
+ buttonText = 'The proposed title already exists';
+ } else if ( pageAlreadyExists ) {
errorHtml = 'Whoops, the page "' + linkToPage + '" already exists.';
buttonText = 'The proposed title already exists';
} else {
// If the page doesn't exist but IS create-protected and the
// current reviewer is not an admin, also display an error
// FIXME: offer one-click request unprotection?
- $.each( data.query.pages[ '-1' ].protection, function ( _, entry ) {
+ $.each( infoResult.query.pages[ '-1' ].protection, function ( _, entry ) {
if ( entry.type === 'create' && entry.level === 'sysop' && $.inArray( 'sysop', mw.config.get( 'wgUserGroups' ) ) === -1 ) {
errorHtml = 'Darn it, "' + linkToPage + '" is create-protected. You will need to request unprotection before accepting.';
buttonText = 'The proposed title is create-protected';
@@ -1828,9 +1837,20 @@
// Show the error message
$status.html( errorHtml );
+ // Add listener for the "Do you want to tag it for speedy deletion so you can accept this draft later?" "yes" link.
+ $( '#afch-redirect-tag-speedy' ).on( 'click', function () {
+ handleAcceptOverRedirect( page.rawTitle );
+ } );
+
+ // Add listener for the "Do you want to tag it for speedy deletion so you can accept this draft later?" "no" link.
+ $( '#afch-redirect-abort' ).on( 'click', function () {
+ $( '#afch-redirect-notification' ).hide();
+ } );
+
// Disable the submit button and show an error in its place
$submitButton
.addClass( 'disabled' )
+ .css( 'pointer-events', 'none' )
.text( buttonText );
} );
} );
@@ -1846,7 +1866,6 @@
existingWPBioTemplateName: existingWPBioTemplateName,
existingShortDescription: shortDescription
} );
-
} );
}
@@ -1937,11 +1956,13 @@
$( this ).removeClass( 'bad-input' );
submitButton
.removeClass( 'disabled' )
+ .css( 'pointer-events', 'auto' )
.text( 'Decline submission' );
} else {
$( this ).addClass( 'bad-input' );
submitButton
.addClass( 'disabled' )
+ .css( 'pointer-events', 'none' )
.text( 'Please enter between one and three URLs!' );
}
} );
@@ -2151,6 +2172,7 @@
$afch.find( '#submitterNameStatus' ).text( '' );
$afch.find( '#afchSubmitForm' )
.removeClass( 'disabled' )
+ .css( 'pointer-events', 'auto' )
.text( 'Submit' );
}
@@ -2188,6 +2210,7 @@
status.text( 'Remove "User:" from the beginning.' );
submitButton
.addClass( 'disabled' )
+ .css( 'pointer-events', 'none' )
.text( 'Invalid user name' );
return;
}
@@ -2203,6 +2226,7 @@
status.text( 'No user named "' + submitter + '".' );
submitButton
.addClass( 'disabled' )
+ .css( 'pointer-events', 'none' )
.text( 'No such user' );
}
} );
@@ -2218,8 +2242,37 @@
addFormSubmitHandler( handlePostponeG13 );
}
- // These functions actually perform a given action using data passed
- // in the `data` parameter.
+ // These functions perform a given action using data passed in the `data` parameter.
+
+ function handleAcceptOverRedirect( destinationPageTitle ) {
+ // get rid of the accept form. replace it with the status div.
+ prepareForProcessing();
+
+ // Add {{Db-afc-move}} speedy deletion tag to redirect, and add to watchlist
+ ( new AFCH.Page( destinationPageTitle ) ).edit( {
+ contents: '{{Db-afc-move|' + afchPage.rawTitle + '}}\n\n',
+ mode: 'prependtext',
+ summary: 'Requesting speedy deletion ([[Wikipedia:CSD#G6|CSD G6]]).',
+ statusText: 'Tagging',
+ watchlist: 'watch'
+ } );
+
+ // Mark the draft as under review.
+ afchPage.getText( false ).then( function ( rawText ) {
+ var text = new AFCH.Text( rawText );
+ afchSubmission.setStatus( 'r', {
+ reviewer: AFCH.consts.user,
+ reviewts: '{{subst:REVISIONTIMESTAMP}}'
+ } );
+ text.updateAfcTemplates( afchSubmission.makeWikicode() );
+ text.cleanUp();
+ afchPage.edit( {
+ contents: text.get(),
+ summary: 'Marking submission as under review',
+ statusText: 'Marking as under review'
+ } );
+ } );
+ }
function handleAccept( data ) {
var newText = data.afchText;