mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-23 14:06:52 +00:00
Implement add a reference edit check
Change-Id: I4cebc5bbaa34300d1c5bb5fde8277269b14779c9
This commit is contained in:
parent
228596cba0
commit
3ece481e71
|
@ -6,6 +6,6 @@
|
|||
/docs/
|
||||
|
||||
# Language files written automatically by TranslateWiki
|
||||
/i18n/**/*.json
|
||||
!/i18n/**/en.json
|
||||
!/i18n/**/qqq.json
|
||||
**/i18n/**/*.json
|
||||
!**/i18n/**/en.json
|
||||
!**/i18n/**/qqq.json
|
||||
|
|
|
@ -180,6 +180,10 @@
|
|||
"value": false,
|
||||
"description": "For testing only. Tag edits for the Edit Check project."
|
||||
},
|
||||
"VisualEditorEditCheck": {
|
||||
"value": false,
|
||||
"description": "Enable experimental Edit Check feature."
|
||||
},
|
||||
"VisualEditorUseSingleEditTab": {
|
||||
"value": false
|
||||
}
|
||||
|
@ -218,7 +222,8 @@
|
|||
"i18n/ve-mw",
|
||||
"i18n/ve-mw/api",
|
||||
"i18n/ve-mw/mwlanguagevariant",
|
||||
"i18n/ve-wmf"
|
||||
"i18n/ve-wmf",
|
||||
"modules/editcheck/i18n"
|
||||
]
|
||||
},
|
||||
"ExtensionMessagesFiles": {
|
||||
|
@ -598,10 +603,32 @@
|
|||
"ext.visualEditor.editCheck": {
|
||||
"group": "visualEditorA",
|
||||
"scripts": [
|
||||
"modules/editcheck/init.js"
|
||||
"modules/editcheck/init.js",
|
||||
"modules/editcheck/EditCheckContextItem.js",
|
||||
"modules/editcheck/EditCheckInspector.js"
|
||||
],
|
||||
"styles": [
|
||||
"modules/editcheck/EditCheck.less"
|
||||
],
|
||||
"dependencies": [
|
||||
"ext.visualEditor.core",
|
||||
"ext.visualEditor.mwsave"
|
||||
],
|
||||
"messages": [
|
||||
"editcheck-dialog-action-no",
|
||||
"editcheck-dialog-action-yes",
|
||||
"editcheck-dialog-addref-description",
|
||||
"editcheck-dialog-addref-reject-question",
|
||||
"editcheck-dialog-addref-reject-description",
|
||||
"editcheck-dialog-addref-reject-no-info",
|
||||
"editcheck-dialog-addref-reject-already-cited",
|
||||
"editcheck-dialog-addref-reject-not-sure",
|
||||
"editcheck-dialog-addref-reject-other",
|
||||
"editcheck-dialog-addref-success-notify",
|
||||
"editcheck-dialog-addref-title",
|
||||
"editcheck-dialog-title",
|
||||
"visualeditor-backbutton-tooltip"
|
||||
],
|
||||
"dependencies": [],
|
||||
"messages": [],
|
||||
"targets": [
|
||||
"desktop",
|
||||
"mobile"
|
||||
|
|
|
@ -1113,6 +1113,7 @@ class Hooks implements TextSlotDiffRendererTablePrefixHook {
|
|||
),
|
||||
'useChangeTagging' => $veConfig->get( 'VisualEditorUseChangeTagging' ),
|
||||
'editCheckTagging' => $veConfig->get( 'VisualEditorEditCheckTagging' ),
|
||||
'editCheck' => $veConfig->get( 'VisualEditorEditCheck' ),
|
||||
'namespacesWithSubpages' => $namespacesWithSubpagesEnabled,
|
||||
'specialBooksources' => urldecode( SpecialPage::getTitleFor( 'Booksources' )->getPrefixedURL() ),
|
||||
'rebaserUrl' => $coreConfig->get( 'VisualEditorRebaserURL' ),
|
||||
|
|
35
modules/editcheck/EditCheck.less
Normal file
35
modules/editcheck/EditCheck.less
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* Toolbar */
|
||||
|
||||
.ve-ui-toolbar-group-title {
|
||||
font-weight: bold;
|
||||
flex: 5 !important; /* stylelint-disable-line declaration-no-important */
|
||||
line-height: 3em;
|
||||
}
|
||||
|
||||
/* Context item */
|
||||
|
||||
.ve-ui-editCheckContextItem {
|
||||
> .ve-ui-linearContextItem-head {
|
||||
background: #fce7fe;
|
||||
}
|
||||
|
||||
&-actions {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Selections */
|
||||
|
||||
.ve-ce-surface-selections-editCheck .ve-ce-surface-selection {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.ve-ce-surface-selections-editCheck .ve-ce-surface-selection > div {
|
||||
mix-blend-mode: darken;
|
||||
// Adjust target colours to account for 50% opacity
|
||||
background: ( #fce7fe - 0.8 * ( #fff ) ) / 0.2;
|
||||
// border: 1px solid ( ( #d02aac - 0.8 * ( #fff ) ) / 0.2 );
|
||||
border-radius: 2px;
|
||||
padding: 2px;
|
||||
margin: -2px 0 0 -2px;
|
||||
}
|
126
modules/editcheck/EditCheckContextItem.js
Normal file
126
modules/editcheck/EditCheckContextItem.js
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*!
|
||||
* VisualEditor EditCheckContextItem class.
|
||||
*
|
||||
* @copyright 2011-2019 VisualEditor Team and others; see http://ve.mit-license.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* Context item shown after a rich text paste.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ui.PersistentContextItem
|
||||
*
|
||||
* @constructor
|
||||
* @param {ve.ui.LinearContext} context Context the item is in
|
||||
* @param {ve.dm.Model} model Model the item is related to
|
||||
* @param {Object} [config]
|
||||
*/
|
||||
ve.ui.EditCheckContextItem = function VeUiEditCheckContextItem() {
|
||||
// Parent constructor
|
||||
ve.ui.EditCheckContextItem.super.apply( this, arguments );
|
||||
|
||||
// Initialization
|
||||
this.$element.addClass( 've-ui-editCheckContextItem' );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
OO.inheritClass( ve.ui.EditCheckContextItem, ve.ui.PersistentContextItem );
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ui.EditCheckContextItem.static.name = 'editCheck';
|
||||
|
||||
ve.ui.EditCheckContextItem.static.icon = 'quotes';
|
||||
|
||||
ve.ui.EditCheckContextItem.static.label = OO.ui.deferMsg( 'editcheck-dialog-addref-title' );
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ve.ui.EditCheckContextItem.prototype.renderBody = function () {
|
||||
// Prompt panel
|
||||
var acceptButton = new OO.ui.ButtonWidget( {
|
||||
label: ve.msg( 'editcheck-dialog-action-yes' ),
|
||||
icon: 'check'
|
||||
} );
|
||||
var rejectButton = new OO.ui.ButtonWidget( {
|
||||
label: ve.msg( 'editcheck-dialog-action-no' ),
|
||||
icon: 'close'
|
||||
} );
|
||||
|
||||
acceptButton.connect( this, { click: 'onAcceptClick' } );
|
||||
rejectButton.connect( this, { click: 'onRejectClick' } );
|
||||
|
||||
// HACK: Suppress close button on mobile context
|
||||
if ( this.context.isMobile() ) {
|
||||
this.context.closeButton.toggle( false );
|
||||
}
|
||||
|
||||
this.$body.append(
|
||||
$( '<p>' ).text( ve.msg( 'editcheck-dialog-addref-description' ) ),
|
||||
$( '<div>' ).addClass( 've-ui-editCheckContextItem-actions' ).append(
|
||||
acceptButton.$element, rejectButton.$element
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
ve.ui.EditCheckContextItem.prototype.close = function ( data ) {
|
||||
// HACK: Un-suppress close button on mobile context
|
||||
if ( this.context.isMobile() ) {
|
||||
this.context.closeButton.toggle( true );
|
||||
}
|
||||
this.data.saveProcessDeferred.resolve( data );
|
||||
};
|
||||
|
||||
ve.ui.EditCheckContextItem.prototype.onAcceptClick = function () {
|
||||
var contextItem = this;
|
||||
var fragment = this.data.fragment;
|
||||
var windowAction = ve.ui.actionFactory.create( 'window', this.context.getSurface() );
|
||||
fragment.collapseToEnd().select();
|
||||
|
||||
windowAction.open( 'citoid' ).then( function ( instance ) {
|
||||
return instance.closing;
|
||||
} ).then( function ( data ) {
|
||||
if ( !data ) {
|
||||
// Reference was not inserted - re-open this context
|
||||
setTimeout( function () {
|
||||
// Deactivate again for mobile after teardown has modified selections
|
||||
contextItem.context.getSurface().getView().deactivate();
|
||||
contextItem.context.afterContextChange();
|
||||
}, 500 );
|
||||
} else {
|
||||
// Edit check inspector is already closed by this point, but
|
||||
// we need to end the workflow.
|
||||
contextItem.close( data );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
ve.ui.EditCheckContextItem.prototype.onRejectClick = function () {
|
||||
var contextItem = this;
|
||||
var windowAction = ve.ui.actionFactory.create( 'window', this.context.getSurface() );
|
||||
windowAction.open(
|
||||
'editCheckInspector',
|
||||
{
|
||||
fragment: this.data.fragment,
|
||||
saveProcessDeferred: this.data.saveProcessDeferred
|
||||
}
|
||||
).then( function ( instance ) {
|
||||
// contextItem.openingCitoid = false;
|
||||
return instance.closing;
|
||||
} ).then( function ( data ) {
|
||||
if ( !data ) {
|
||||
// Form was closed, re-open this context
|
||||
contextItem.context.afterContextChange();
|
||||
} else {
|
||||
contextItem.close( data );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ui.contextItemFactory.register( ve.ui.EditCheckContextItem );
|
151
modules/editcheck/EditCheckInspector.js
Normal file
151
modules/editcheck/EditCheckInspector.js
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*!
|
||||
* VisualEditor UserInterface EditCheckInspector class.
|
||||
*
|
||||
* @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edit check inspector
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ui.FragmentInspector
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} [config] Configuration options
|
||||
*/
|
||||
ve.ui.EditCheckInspector = function VeUiEditCheckInspector( config ) {
|
||||
// Parent constructor
|
||||
ve.ui.EditCheckInspector.super.call( this, config );
|
||||
|
||||
// Pre-initialization
|
||||
this.$element.addClass( 've-ui-editCheckInspector' );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
OO.inheritClass( ve.ui.EditCheckInspector, ve.ui.FragmentInspector );
|
||||
|
||||
ve.ui.EditCheckInspector.static.name = 'editCheckInspector';
|
||||
|
||||
// ve.ui.EditCheckInspector.static.title = OO.ui.deferMsg( 'editcheck-dialog-title' );
|
||||
ve.ui.EditCheckInspector.static.title = OO.ui.deferMsg( 'editcheck-dialog-addref-title' );
|
||||
|
||||
// ve.ui.EditCheckInspector.static.size = 'context';
|
||||
|
||||
ve.ui.EditCheckInspector.static.actions = [
|
||||
{
|
||||
label: OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ),
|
||||
flags: [ 'safe', 'back' ],
|
||||
modes: [ 'mobile', 'desktop' ]
|
||||
},
|
||||
{
|
||||
action: 'continue',
|
||||
icon: 'next',
|
||||
flags: [ 'primary', 'progressive' ],
|
||||
modes: [ 'mobile' ]
|
||||
}
|
||||
];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ve.ui.EditCheckInspector.prototype.initialize = function () {
|
||||
// Parent method
|
||||
ve.ui.EditCheckInspector.super.prototype.initialize.call( this );
|
||||
|
||||
// Survey panel
|
||||
this.answerRadioSelect = new OO.ui.RadioSelectWidget( {
|
||||
items: [
|
||||
new OO.ui.RadioOptionWidget( {
|
||||
data: 'no-info',
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-no-info' )
|
||||
} ),
|
||||
new OO.ui.RadioOptionWidget( {
|
||||
data: 'already-cited',
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-already-cited' )
|
||||
} ),
|
||||
new OO.ui.RadioOptionWidget( {
|
||||
data: 'not-sure',
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-not-sure' )
|
||||
} ),
|
||||
new OO.ui.RadioOptionWidget( {
|
||||
data: 'other',
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-other' )
|
||||
} )
|
||||
]
|
||||
} );
|
||||
this.answerRadioSelect.connect( this, { select: 'updateActions' } );
|
||||
|
||||
this.answerConfirm = new OO.ui.ButtonWidget( {
|
||||
flags: [ 'progressive' ],
|
||||
framed: false,
|
||||
label: 'Continue',
|
||||
disabled: true
|
||||
} );
|
||||
this.answerConfirm.toggle( !OO.ui.isMobile() );
|
||||
this.answerConfirm.connect( this, { click: [ 'executeAction', 'continue' ] } );
|
||||
|
||||
this.form.addItems(
|
||||
new OO.ui.FieldsetLayout( {
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-question' ),
|
||||
items: [
|
||||
new OO.ui.FieldLayout( this.answerRadioSelect, {
|
||||
label: ve.msg( 'editcheck-dialog-addref-reject-description' ),
|
||||
align: 'top'
|
||||
} ),
|
||||
new OO.ui.FieldLayout( this.answerConfirm, {
|
||||
align: 'left'
|
||||
} )
|
||||
]
|
||||
} )
|
||||
);
|
||||
};
|
||||
|
||||
ve.ui.EditCheckInspector.prototype.updateActions = function () {
|
||||
this.answerConfirm.setDisabled( !this.answerRadioSelect.findSelectedItem() );
|
||||
};
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ve.ui.EditCheckInspector.prototype.getSetupProcess = function ( data ) {
|
||||
data = data || {};
|
||||
return ve.ui.EditCheckInspector.super.prototype.getSetupProcess.call( this, data )
|
||||
.first( function () {
|
||||
this.surface = data.surface;
|
||||
this.saveProcessDeferred = data.saveProcessDeferred;
|
||||
this.answerRadioSelect.selectItem( null );
|
||||
}, this );
|
||||
};
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ve.ui.EditCheckInspector.prototype.getReadyProcess = function ( data ) {
|
||||
return ve.ui.EditCheckInspector.super.prototype.getReadyProcess.call( this, data )
|
||||
.first( function () {
|
||||
this.actions.setMode( OO.ui.isMobile() ? 'mobile' : 'desktop' );
|
||||
}, this );
|
||||
};
|
||||
|
||||
ve.ui.EditCheckInspector.prototype.getActionProcess = function ( action ) {
|
||||
if ( action === '' ) {
|
||||
return new OO.ui.Process( function () {
|
||||
this.close();
|
||||
}, this );
|
||||
}
|
||||
|
||||
if ( action === 'continue' ) {
|
||||
return new OO.ui.Process( function () {
|
||||
this.close( { action: 'reject', reason: this.answerRadioSelect.findSelectedItem().getData() } );
|
||||
}, this );
|
||||
}
|
||||
|
||||
return ve.ui.EditCheckInspector.super.prototype.getActionProcess.call( this, action );
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ui.windowFactory.register( ve.ui.EditCheckInspector );
|
14
modules/editcheck/i18n/en.json
Normal file
14
modules/editcheck/i18n/en.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"editcheck-dialog-action-no": "No",
|
||||
"editcheck-dialog-action-yes": "Yes",
|
||||
"editcheck-dialog-addref-description": "Help readers understand where this information is coming from by adding a citation.",
|
||||
"editcheck-dialog-addref-reject-question": "Why are you not adding a citation?",
|
||||
"editcheck-dialog-addref-reject-description": "Other editors would value learning more about your decision to dismiss the citation.",
|
||||
"editcheck-dialog-addref-reject-no-info": "I didn't add new information",
|
||||
"editcheck-dialog-addref-reject-already-cited": "My changes are already cited earlier",
|
||||
"editcheck-dialog-addref-reject-not-sure": "I'm not sure what citation to add",
|
||||
"editcheck-dialog-addref-reject-other": "Other",
|
||||
"editcheck-dialog-addref-success-notify": "Thank you for adding a citation!",
|
||||
"editcheck-dialog-addref-title": "Add a citation",
|
||||
"editcheck-dialog-title": "Before publishing"
|
||||
}
|
14
modules/editcheck/i18n/fr.json
Normal file
14
modules/editcheck/i18n/fr.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"editcheck-dialog-action-no": "Non",
|
||||
"editcheck-dialog-action-yes": "Oui",
|
||||
"editcheck-dialog-addref-description": "Aidez les lecteurs à comprendre d'où proviennent ces informations en ajoutant une source.",
|
||||
"editcheck-dialog-addref-reject-question": "Pourquoi n'ajoutez-vous pas une source ?",
|
||||
"editcheck-dialog-addref-reject-description": "Les autres éditeurs aimeraient en savoir plus sur votre décision de ne pas ajouter une source.",
|
||||
"editcheck-dialog-addref-reject-no-info": "Je n'ai pas ajouté de nouvelles informations",
|
||||
"editcheck-dialog-addref-reject-already-cited": "Mes modifications sont déjà sourcées plus haut",
|
||||
"editcheck-dialog-addref-reject-not-sure": "Je ne sais pas quelle source ajouter",
|
||||
"editcheck-dialog-addref-reject-other": "Autre",
|
||||
"editcheck-dialog-addref-success-notify": "Merci d'avoir ajouté une source !",
|
||||
"editcheck-dialog-addref-title": "Ajouter une source",
|
||||
"editcheck-dialog-title": "Avant de publier"
|
||||
}
|
14
modules/editcheck/i18n/qqq.json
Normal file
14
modules/editcheck/i18n/qqq.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"editcheck-dialog-action-no": "Label for the no option when asking users if they want to add a citation.",
|
||||
"editcheck-dialog-action-yes": "Label for the no option when asking users if they want to add a citation.",
|
||||
"editcheck-dialog-addref-description": "Help text explaining why it is helpful to add a citation.",
|
||||
"editcheck-dialog-addref-reject-question": "Heading for form question asking why the user didn't add a citation.",
|
||||
"editcheck-dialog-addref-reject-description": "Help text for form question asking why the user didn't add a citation.",
|
||||
"editcheck-dialog-addref-reject-no-info": "Answer option in repsonse to {{msg-mw|editcheck-dialog-addref-reject-question}}",
|
||||
"editcheck-dialog-addref-reject-already-cited": "Answer option in repsonse to {{msg-mw|editcheck-dialog-addref-reject-question}}",
|
||||
"editcheck-dialog-addref-reject-not-sure": "Answer option in repsonse to {{msg-mw|editcheck-dialog-addref-reject-question}}",
|
||||
"editcheck-dialog-addref-reject-other": "Answer option in repsonse to {{msg-mw|editcheck-dialog-addref-reject-question}}",
|
||||
"editcheck-dialog-addref-success-notify": "Notification messages shown after a citation is added successfully.",
|
||||
"editcheck-dialog-addref-title": "Title for the edit check context asking user to add a citation.",
|
||||
"editcheck-dialog-title": "Title shown in the toolbar while the user is in the add a citation workflow."
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
mw.editcheck = {};
|
||||
|
||||
/**
|
||||
* Check if added content in the document model might need a reference
|
||||
* Find added content in the document model that might need a reference
|
||||
*
|
||||
* @param {ve.dm.DocumentModel} documentModel Document model
|
||||
* @param {boolean} [includeReferencedContent] Include content ranges that already
|
||||
* have a reference.
|
||||
* @return {boolean}
|
||||
* @return {ve.dm.Selection[]} Content ranges that might need a reference
|
||||
*/
|
||||
mw.editcheck.doesAddedContentNeedReference = function ( documentModel, includeReferencedContent ) {
|
||||
mw.editcheck.findAddedContentNeedingReference = function ( documentModel, includeReferencedContent ) {
|
||||
if ( mw.config.get( 'wgNamespaceNumber' ) !== mw.config.get( 'wgNamespaceIds' )[ '' ] ) {
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
|
||||
if ( !documentModel.completeHistory.getLength() ) {
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
var operations;
|
||||
try {
|
||||
|
@ -23,7 +23,7 @@ mw.editcheck.doesAddedContentNeedReference = function ( documentModel, includeRe
|
|||
// TransactionSquasher can sometimes throw errors; until T333710 is
|
||||
// fixed just count this as not needing a reference.
|
||||
mw.errorLogger.logError( err, 'error.visualeditor' );
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
|
||||
var ranges = [];
|
||||
|
@ -45,7 +45,7 @@ mw.editcheck.doesAddedContentNeedReference = function ( documentModel, includeRe
|
|||
// Reached the end of the doc / start of internal list, stop searching
|
||||
return offset < endOffset;
|
||||
} );
|
||||
return ranges.some( function ( range ) {
|
||||
var addedTextRanges = ranges.filter( function ( range ) {
|
||||
var minimumCharacters = 50;
|
||||
// 1. Check that at least minimumCharacters characters have been inserted sequentially
|
||||
if ( range.getLength() >= minimumCharacters ) {
|
||||
|
@ -66,6 +66,10 @@ mw.editcheck.doesAddedContentNeedReference = function ( documentModel, includeRe
|
|||
}
|
||||
return false;
|
||||
} );
|
||||
|
||||
return addedTextRanges.map( function ( range ) {
|
||||
return new ve.dm.LinearSelection( range );
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -118,3 +122,152 @@ if ( mw.config.get( 'wgVisualEditorConfig' ).editCheckTagging ) {
|
|||
};
|
||||
} );
|
||||
}
|
||||
|
||||
if ( mw.config.get( 'wgVisualEditorConfig' ).editCheck ) {
|
||||
mw.hook( 've.preSaveProcess' ).add( function ( saveProcess, target ) {
|
||||
var surface = target.getSurface();
|
||||
|
||||
var selections = mw.editcheck.findAddedContentNeedingReference( surface.getModel().getDocument() );
|
||||
|
||||
if ( selections.length ) {
|
||||
var surfaceView = surface.getView();
|
||||
var toolbar = target.getToolbar();
|
||||
var reviewToolbar = new ve.ui.PositionedTargetToolbar( target, target.toolbarConfig );
|
||||
reviewToolbar.setup( [
|
||||
{
|
||||
name: 'back',
|
||||
type: 'bar',
|
||||
include: [ 'editCheckBack' ]
|
||||
},
|
||||
// Placeholder toolbar groups
|
||||
// TODO: Make a proper TitleTool?
|
||||
{
|
||||
name: 'title',
|
||||
type: 'bar',
|
||||
include: []
|
||||
},
|
||||
{
|
||||
name: 'save',
|
||||
// TODO: MobileArticleTarget should ignore 'align'
|
||||
align: OO.ui.isMobile() ? 'before' : 'after',
|
||||
type: 'bar',
|
||||
include: [ 'showSaveDisabled' ]
|
||||
}
|
||||
], surface );
|
||||
|
||||
reviewToolbar.items[ 1 ].$element.removeClass( 'oo-ui-toolGroup-empty' );
|
||||
reviewToolbar.items[ 1 ].$group.append(
|
||||
$( '<span>' ).addClass( 've-ui-editCheck-toolbar-title' ).text( ve.msg( 'editcheck-dialog-title' ) )
|
||||
);
|
||||
if ( OO.ui.isMobile() ) {
|
||||
reviewToolbar.$element.addClass( 've-init-mw-mobileArticleTarget-toolbar' );
|
||||
}
|
||||
target.toolbar.$element.before( reviewToolbar.$element );
|
||||
target.toolbar = reviewToolbar;
|
||||
|
||||
var selection = selections[ 0 ];
|
||||
var highlightNodes = surfaceView.getDocument().selectNodes( selection.getCoveringRange(), 'branches' ).map( function ( spec ) {
|
||||
return spec.node;
|
||||
} );
|
||||
|
||||
surfaceView.drawSelections( 'editCheck', [ ve.ce.Selection.static.newFromModel( selection, surfaceView ) ] );
|
||||
surfaceView.setReviewMode( true, highlightNodes );
|
||||
toolbar.toggle( false );
|
||||
target.onContainerScroll();
|
||||
|
||||
saveProcess.next( function () {
|
||||
var saveProcessDeferred = ve.createDeferred();
|
||||
var fragment = surface.getModel().getFragment( selection, true );
|
||||
|
||||
var context = surface.getContext();
|
||||
|
||||
// Select the found content to correctly the context on desktop
|
||||
fragment.select();
|
||||
// Deactivate to prevent selection suppressing mobile context
|
||||
surface.getView().deactivate();
|
||||
|
||||
context.addPersistentSource( {
|
||||
embeddable: false,
|
||||
data: {
|
||||
fragment: fragment,
|
||||
saveProcessDeferred: saveProcessDeferred
|
||||
},
|
||||
name: 'editCheck'
|
||||
} );
|
||||
|
||||
// Once the context is positioned, clear the selection
|
||||
setTimeout( function () {
|
||||
surface.getModel().setNullSelection();
|
||||
} );
|
||||
|
||||
return saveProcessDeferred.promise().then( function ( data ) {
|
||||
context.removePersistentSource( 'editCheck' );
|
||||
|
||||
surfaceView.drawSelections( 'editCheck', [] );
|
||||
surfaceView.setReviewMode( false );
|
||||
|
||||
reviewToolbar.$element.remove();
|
||||
toolbar.toggle( true );
|
||||
target.toolbar = toolbar;
|
||||
target.onContainerScroll();
|
||||
|
||||
// Check the user inserted a citation
|
||||
if ( data && data.action ) {
|
||||
if ( data.action !== 'reject' ) {
|
||||
mw.notify( ve.msg( 'editcheck-dialog-addref-success-notify' ), { type: 'success' } );
|
||||
}
|
||||
var delay = ve.createDeferred();
|
||||
// If they inserted, wait 2 seconds on desktop before showing save dialog
|
||||
setTimeout( function () {
|
||||
delay.resolve();
|
||||
}, !OO.ui.isMobile() && data.action !== 'reject' ? 2000 : 0 );
|
||||
return delay.promise();
|
||||
} else {
|
||||
return ve.createDeferred().reject().promise();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
ve.ui.EditCheckBack = function VeUiEditCheckBack() {
|
||||
// Parent constructor
|
||||
ve.ui.EditCheckBack.super.apply( this, arguments );
|
||||
|
||||
this.setDisabled( false );
|
||||
};
|
||||
OO.inheritClass( ve.ui.EditCheckBack, ve.ui.Tool );
|
||||
ve.ui.EditCheckBack.static.name = 'editCheckBack';
|
||||
ve.ui.EditCheckBack.static.icon = 'previous';
|
||||
ve.ui.EditCheckBack.static.autoAddToCatchall = false;
|
||||
ve.ui.EditCheckBack.static.autoAddToGroup = false;
|
||||
ve.ui.EditCheckBack.static.title =
|
||||
OO.ui.deferMsg( 'visualeditor-backbutton-tooltip' );
|
||||
ve.ui.EditCheckBack.prototype.onSelect = function () {
|
||||
var context = this.toolbar.getSurface().getContext();
|
||||
if ( context.inspector ) {
|
||||
context.inspector.close();
|
||||
} else {
|
||||
context.items[ 0 ].close();
|
||||
}
|
||||
this.setActive( false );
|
||||
};
|
||||
ve.ui.EditCheckBack.prototype.onUpdateState = function () {
|
||||
this.setDisabled( false );
|
||||
};
|
||||
ve.ui.toolFactory.register( ve.ui.EditCheckBack );
|
||||
|
||||
ve.ui.EditCheckSaveDisabled = function VeUiEditCheckSaveDisabled() {
|
||||
// Parent constructor
|
||||
ve.ui.EditCheckSaveDisabled.super.apply( this, arguments );
|
||||
};
|
||||
OO.inheritClass( ve.ui.EditCheckSaveDisabled, ve.ui.MWSaveTool );
|
||||
ve.ui.EditCheckSaveDisabled.static.name = 'showSaveDisabled';
|
||||
ve.ui.EditCheckSaveDisabled.static.autoAddToCatchall = false;
|
||||
ve.ui.EditCheckSaveDisabled.static.autoAddToGroup = false;
|
||||
ve.ui.EditCheckSaveDisabled.prototype.onUpdateState = function () {
|
||||
this.setDisabled( true );
|
||||
};
|
||||
|
||||
ve.ui.toolFactory.register( ve.ui.EditCheckSaveDisabled );
|
||||
|
|
|
@ -1548,11 +1548,11 @@ ve.init.mw.ArticleTarget.prototype.save = function ( doc, options ) {
|
|||
) {
|
||||
var documentModel = this.getSurface().getModel().getDocument();
|
||||
// New content needing a reference
|
||||
if ( mw.editcheck.doesAddedContentNeedReference( documentModel ) ) {
|
||||
if ( mw.editcheck.findAddedContentNeedingReference( documentModel ).length ) {
|
||||
taglist.push( 'editcheck-references' );
|
||||
}
|
||||
// New content, regardless of if it needs a reference
|
||||
if ( mw.editcheck.doesAddedContentNeedReference( documentModel, true ) ) {
|
||||
if ( mw.editcheck.findAddedContentNeedingReference( documentModel, true ).length ) {
|
||||
taglist.push( 'editcheck-newcontent' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
modules.push( 'ext.visualEditor.mwwikitext' );
|
||||
}
|
||||
|
||||
if ( conf.editCheckTagging ) {
|
||||
if ( conf.editCheckTagging || conf.editCheck ) {
|
||||
modules.push( 'ext.visualEditor.editCheck' );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue