mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/ConfirmEdit
synced 2024-11-11 17:00:49 +00:00
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:
parent
eeb6b47172
commit
1f0d203065
|
@ -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"
|
||||
|
|
6
resources/ve-confirmedit/.eslintrc.json
Normal file
6
resources/ve-confirmedit/.eslintrc.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"globals": {
|
||||
"ve": false,
|
||||
"OO": false
|
||||
}
|
||||
}
|
115
resources/ve-confirmedit/ve.init.ConfirmEdit.init.js
Normal file
115
resources/ve-confirmedit/ve.init.ConfirmEdit.init.js
Normal 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;
|
||||
} );
|
||||
} );
|
Loading…
Reference in a new issue