Move VE's ConfirmEdit support to this extension

This can be merged before the code is dropped from VE, as
it will just overwrite the registry entry.

Bug: T141676
Depends-On: I2c35b9443208928db43bcfd515864641b10cc602
Change-Id: I2fa7ca7203e0a82f5ce9b79e2642dba2baba6c5a
This commit is contained in:
Ed Sanders 2018-11-23 17:22:13 +00:00
parent eeb6b47172
commit 1f0d203065
3 changed files with 127 additions and 0 deletions

View file

@ -70,8 +70,14 @@
"ResourceModules": {
"ext.confirmEdit.editPreview.ipwhitelist.styles": {
"styles": "ext.confirmEdit.editPreview.ipwhitelist.styles.css"
},
"ext.confirmEdit.visualEditor": {
"scripts": "ve-confirmedit/ve.init.ConfirmEdit.init.js"
}
},
"VisualEditorPluginModules": [
"ext.confirmEdit.visualEditor"
],
"ResourceFileModulePaths": {
"localBasePath": "resources",
"remoteExtPath": "ConfirmEdit/resources"

View file

@ -0,0 +1,6 @@
{
"globals": {
"ve": false,
"OO": false
}
}

View file

@ -0,0 +1,115 @@
// Extension:ConfirmEdit
// Captcha "errors" usually aren't errors. We simply don't know about them ahead of time,
// so we save once, then (if required) we get an error with a captcha back and try again after
// the user solved the captcha.
// TODO: ConfirmEdit API is horrible, there is no reliable way to know whether it is a "math",
// "question" or "fancy" type of captcha. They all expose differently named properties in the
// API for different things in the UI. At this point we only support the SimpleCaptcha and FancyCaptcha
// which we very intuitively detect by the presence of a "url" property.
mw.libs.ve.targetLoader.addPlugin( function () {
ve.init.mw.saveErrorHandlerRegistry.register( 'confirmEditCaptchas', function ( editApi, target ) {
var $captchaImg, msg, question,
captchaInput, $captchaDiv, $captchaParagraph,
captchaData = editApi.captcha;
if ( !(
captchaData && (
captchaData.url ||
captchaData.type === 'simple' ||
captchaData.type === 'math' ||
captchaData.type === 'question'
)
) ) {
return false;
}
captchaInput = new OO.ui.TextInputWidget( { classes: [ 've-ui-saveDialog-captchaInput' ] } );
function onCaptchaLoad() {
target.saveDialog.updateSize();
captchaInput.focus();
captchaInput.scrollElementIntoView();
}
// Save when pressing 'Enter' in captcha field as it is single line.
captchaInput.on( 'enter', function () {
target.saveDialog.executeAction( 'save' );
} );
// Register extra fields
target.saveFields.wpCaptchaId = function () {
return captchaData.id;
};
target.saveFields.wpCaptchaWord = function () {
return captchaInput.getValue();
};
target.saveDialog.once( 'save', function () {
// Unregister extra fields on save attempt
delete target.saveFields.wpCaptchaId;
delete target.saveFields.wpCaptchaWord;
} );
$captchaParagraph = $( '<p>' ).append(
$( '<strong>' ).text( mw.msg( 'captcha-label' ) ),
document.createTextNode( mw.msg( 'colon-separator' ) )
);
$captchaDiv = $( '<div>' ).append( $captchaParagraph );
if ( captchaData.url ) {
// FancyCaptcha
// Based on FancyCaptcha::getFormInformation() (https://git.io/v6mml) and
// ext.confirmEdit.fancyCaptcha.js in the ConfirmEdit extension.
mw.loader.load( 'ext.confirmEdit.fancyCaptcha' );
$captchaDiv.addClass( 'fancycaptcha-captcha-container' );
$captchaParagraph.append(
$( $.parseHTML( mw.message( 'fancycaptcha-edit' ).parse() ) )
.filter( 'a' ).attr( 'target', '_blank' ).end()
);
$captchaImg = $( '<img>' )
.attr( 'src', captchaData.url )
.addClass( 'fancycaptcha-image' )
.on( 'load', onCaptchaLoad );
$captchaDiv.append(
$captchaImg,
' ',
$( '<a>' ).addClass( 'fancycaptcha-reload' ).text( mw.msg( 'fancycaptcha-reload-text' ) )
);
} else {
if ( captchaData.type === 'simple' || captchaData.type === 'math' ) {
// SimpleCaptcha and MathCaptcha
msg = 'captcha-edit';
} else if ( captchaData.type === 'question' ) {
// QuestyCaptcha
msg = 'questycaptcha-edit';
}
if ( msg ) {
switch ( captchaData.mime ) {
case 'text/html':
question = $.parseHTML( captchaData.question );
// TODO: Search for images and wait for them to load
setTimeout( onCaptchaLoad );
break;
case 'text/plain':
question = document.createTextNode( captchaData.question );
setTimeout( onCaptchaLoad );
break;
}
$captchaParagraph.append( mw.message( msg ).parse(), '<br>', question );
}
}
$captchaDiv.append( captchaInput.$element );
// ProcessDialog's error system isn't great for this yet.
target.saveDialog.clearMessage( 'api-save-error' );
target.saveDialog.showMessage( 'api-save-error', $captchaDiv );
target.saveDialog.popPending();
// Emit event for tracking. TODO: This is a bad design
target.emit( 'saveErrorCaptcha' );
return true;
} );
} );