mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Cite
synced 2024-11-23 22:45:20 +00:00
Merge "Introduce MWReferenceEditPanel to extract editing UI"
This commit is contained in:
commit
e5b4d9edfb
|
@ -110,6 +110,7 @@
|
|||
"ve.ui.MWReferencesListDialog.js",
|
||||
"ve.ui.MWReferenceDialog.js",
|
||||
"ve.ui.MWReferenceDialogTool.js",
|
||||
"ve.ui.MWReferenceEditPanel.js",
|
||||
"ve.ui.MWCitationDialogTool.js",
|
||||
"ve.ui.MWReferenceContextItem.js",
|
||||
"ve.ui.MWReferencesListContextItem.js",
|
||||
|
|
|
@ -154,8 +154,8 @@ ve.ui.MWReferenceDialog.prototype.documentHasContent = function () {
|
|||
*/
|
||||
ve.ui.MWReferenceDialog.prototype.isModified = function () {
|
||||
return this.documentHasContent() &&
|
||||
( this.referenceTarget.hasBeenModified() ||
|
||||
this.referenceGroupInput.getValue() !== this.originalGroup );
|
||||
( this.editPanel.referenceTarget.hasBeenModified() ||
|
||||
this.editPanel.referenceGroupInput.getValue() !== this.originalGroup );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -218,7 +218,7 @@ ve.ui.MWReferenceDialog.prototype.getReadyProcess = function ( data ) {
|
|||
if ( this.reuseReference ) {
|
||||
this.reuseSearch.getQuery().focus().select();
|
||||
} else {
|
||||
this.referenceTarget.focus();
|
||||
this.editPanel.referenceTarget.focus();
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
@ -259,13 +259,13 @@ ve.ui.MWReferenceDialog.prototype.setReferenceForEditing = function ( ref ) {
|
|||
* @param {ve.dm.MWReferenceModel} ref
|
||||
*/
|
||||
ve.ui.MWReferenceDialog.prototype.setFormFieldsFromRef = function ( ref ) {
|
||||
this.referenceTarget.setDocument( ref.getDocument() );
|
||||
this.editPanel.referenceTarget.setDocument( ref.getDocument() );
|
||||
|
||||
this.originalGroup = ref.getGroup();
|
||||
// Set the group input while it's disabled, so this doesn't pop up the group-picker menu
|
||||
this.referenceGroupInput.setDisabled( true );
|
||||
this.referenceGroupInput.setValue( this.originalGroup );
|
||||
this.referenceGroupInput.setDisabled( false );
|
||||
this.editPanel.referenceGroupInput.setDisabled( true );
|
||||
this.editPanel.referenceGroupInput.setValue( this.originalGroup );
|
||||
this.editPanel.referenceGroupInput.setDisabled( false );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -280,7 +280,7 @@ ve.ui.MWReferenceDialog.prototype.updateReuseWarningFromRef = function ( ref ) {
|
|||
( node ) => !node.findParent( ve.dm.MWReferencesListNode )
|
||||
).length : 0;
|
||||
|
||||
this.reuseWarning
|
||||
this.editPanel.reuseWarning
|
||||
.toggle( usages > 1 )
|
||||
.setLabel( mw.msg( 'cite-ve-dialog-reference-editing-reused-long', usages ) );
|
||||
};
|
||||
|
@ -300,7 +300,7 @@ ve.ui.MWReferenceDialog.prototype.updateExtendsWarningFromRef = function ( ref )
|
|||
) );
|
||||
}
|
||||
|
||||
this.extendsWarning.toggle( !!ref.extendsRef );
|
||||
this.editPanel.extendsWarning.toggle( !!ref.extendsRef );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -312,66 +312,20 @@ ve.ui.MWReferenceDialog.prototype.initialize = function () {
|
|||
|
||||
// Properties
|
||||
this.panels = new OO.ui.StackLayout();
|
||||
this.editPanel = new OO.ui.PanelLayout( {
|
||||
scrollable: true, padded: true
|
||||
} );
|
||||
this.editPanel = new ve.ui.MWReferenceEditPanel( { $overlay: this.$overlay } );
|
||||
this.reuseSearchPanel = new OO.ui.PanelLayout();
|
||||
|
||||
this.reuseWarning = new OO.ui.MessageWidget( {
|
||||
inline: true,
|
||||
icon: 'alert',
|
||||
classes: [ 've-ui-mwReferenceDialog-reuseWarning' ]
|
||||
} );
|
||||
|
||||
// Icon message widget
|
||||
this.extendsWarning = new OO.ui.MessageWidget( {
|
||||
icon: 'alert',
|
||||
inline: true,
|
||||
classes: [ 've-ui-mwReferenceDialog-extendsWarning' ]
|
||||
} );
|
||||
|
||||
const citeCommands = Object.keys( ve.init.target.getSurface().commandRegistry.registry )
|
||||
.filter( ( command ) => command.indexOf( 'cite-' ) !== -1 );
|
||||
|
||||
this.referenceTarget = ve.init.target.createTargetWidget(
|
||||
{
|
||||
includeCommands: this.constructor.static.includeCommands,
|
||||
excludeCommands: this.constructor.static.excludeCommands.concat( citeCommands ),
|
||||
importRules: this.constructor.static.getImportRules(),
|
||||
inDialog: this.constructor.static.name,
|
||||
placeholder: ve.msg( 'cite-ve-dialog-reference-placeholder' )
|
||||
}
|
||||
);
|
||||
|
||||
this.contentFieldset = new OO.ui.FieldsetLayout();
|
||||
this.optionsFieldset = new OO.ui.FieldsetLayout( {
|
||||
label: ve.msg( 'cite-ve-dialog-reference-options-section' ),
|
||||
icon: 'settings'
|
||||
} );
|
||||
this.contentFieldset.$element.append( this.referenceTarget.$element );
|
||||
|
||||
this.referenceGroupInput = new ve.ui.MWReferenceGroupInputWidget( {
|
||||
$overlay: this.$overlay,
|
||||
emptyGroupName: ve.msg( 'cite-ve-dialog-reference-options-group-placeholder' )
|
||||
} );
|
||||
this.referenceGroupInput.connect( this, { change: 'onReferenceGroupInputChange' } );
|
||||
this.referenceGroupField = new OO.ui.FieldLayout( this.referenceGroupInput, {
|
||||
align: 'top',
|
||||
label: ve.msg( 'cite-ve-dialog-reference-options-group-label' )
|
||||
} );
|
||||
this.reuseSearch = new ve.ui.MWReferenceSearchWidget();
|
||||
|
||||
// Events
|
||||
this.reuseSearch.getResults().connect( this, { choose: 'onReuseSearchResultsChoose' } );
|
||||
this.referenceTarget.connect( this, { change: 'onTargetChange' } );
|
||||
this.editPanel.referenceTarget.connect( this, { change: 'onTargetChange' } );
|
||||
this.editPanel.referenceGroupInput.connect( this, { change: 'onReferenceGroupInputChange' } );
|
||||
|
||||
// Initialization
|
||||
this.$content.addClass( 've-ui-mwReferenceDialog' );
|
||||
|
||||
this.panels.addItems( [ this.editPanel, this.reuseSearchPanel ] );
|
||||
this.editPanel.$element.append(
|
||||
this.reuseWarning.$element, this.extendsWarning.$element, this.contentFieldset.$element, this.optionsFieldset.$element );
|
||||
this.optionsFieldset.addItems( [ this.referenceGroupField ] );
|
||||
this.reuseSearchPanel.$element.append( this.reuseSearch.$element );
|
||||
this.$body.append( this.panels.$element );
|
||||
};
|
||||
|
@ -397,7 +351,7 @@ ve.ui.MWReferenceDialog.prototype.getActionProcess = function ( action ) {
|
|||
return new OO.ui.Process( () => {
|
||||
const surfaceModel = this.getFragment().getSurface();
|
||||
|
||||
this.referenceModel.setGroup( this.referenceGroupInput.getValue() );
|
||||
this.referenceModel.setGroup( this.editPanel.referenceGroupInput.getValue() );
|
||||
|
||||
// Insert reference (will auto-create an internal item if needed)
|
||||
if ( !( this.selectedNode instanceof ve.dm.MWReferenceNode ) ) {
|
||||
|
@ -440,8 +394,8 @@ ve.ui.MWReferenceDialog.prototype.getSetupProcess = function ( data ) {
|
|||
this.reuseSearch.setInternalList( this.getFragment().getDocument().getInternalList() );
|
||||
|
||||
const isReadOnly = this.isReadOnly();
|
||||
this.referenceTarget.setReadOnly( isReadOnly );
|
||||
this.referenceGroupInput.setReadOnly( isReadOnly );
|
||||
this.editPanel.referenceTarget.setReadOnly( isReadOnly );
|
||||
this.editPanel.referenceGroupInput.setReadOnly( isReadOnly );
|
||||
|
||||
this.reuseReference = !!data.reuseReference;
|
||||
if ( this.reuseReference ) {
|
||||
|
@ -451,7 +405,7 @@ ve.ui.MWReferenceDialog.prototype.getSetupProcess = function ( data ) {
|
|||
done: false
|
||||
} );
|
||||
|
||||
this.referenceGroupInput.populateMenu(
|
||||
this.editPanel.referenceGroupInput.populateMenu(
|
||||
this.getFragment().getDocument().getInternalList() );
|
||||
|
||||
this.trackedInputChange = false;
|
||||
|
@ -464,9 +418,9 @@ ve.ui.MWReferenceDialog.prototype.getSetupProcess = function ( data ) {
|
|||
ve.ui.MWReferenceDialog.prototype.getTeardownProcess = function ( data ) {
|
||||
return ve.ui.MWReferenceDialog.super.prototype.getTeardownProcess.call( this, data )
|
||||
.first( () => {
|
||||
this.referenceTarget.getSurface().getModel().disconnect( this );
|
||||
this.editPanel.referenceTarget.getSurface().getModel().disconnect( this );
|
||||
this.reuseSearch.clearSearch();
|
||||
this.referenceTarget.clear();
|
||||
this.editPanel.referenceTarget.clear();
|
||||
this.referenceModel = null;
|
||||
} );
|
||||
};
|
||||
|
|
179
modules/ve-cite/ve.ui.MWReferenceEditPanel.js
Normal file
179
modules/ve-cite/ve.ui.MWReferenceEditPanel.js
Normal file
|
@ -0,0 +1,179 @@
|
|||
'use strict';
|
||||
|
||||
/*!
|
||||
* VisualEditor UserInterface MWReferenceResultWidget class.
|
||||
*
|
||||
* @copyright 2011-2018 VisualEditor Team's Cite sub-team and others; see AUTHORS.txt
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a ve.ui.MWReferenceEditPanel object.
|
||||
*
|
||||
* @constructor
|
||||
* @extends OO.ui.PanelLayout
|
||||
* @param {Object} config
|
||||
* @param {jQuery} config.$overlay Layer to render options dropdown outside of the parent dialog
|
||||
*/
|
||||
ve.ui.MWReferenceEditPanel = function VeUiMWReferenceEditPanel( config ) {
|
||||
// Configuration initialization
|
||||
config = Object.assign( {
|
||||
scrollable: true,
|
||||
padded: true
|
||||
}, config );
|
||||
|
||||
// Parent constructor
|
||||
ve.ui.MWReferenceEditPanel.super.call( this, { scrollable: true, padded: true } );
|
||||
|
||||
// Initialization
|
||||
this.$element.addClass( 've-ui-mwReferenceEditPanel' );
|
||||
|
||||
// Properties
|
||||
|
||||
// Create content editor
|
||||
this.referenceTarget = ve.init.target.createTargetWidget(
|
||||
{
|
||||
includeCommands: null,
|
||||
excludeCommands: this.constructor.static.getExcludeCommands(),
|
||||
importRules: this.constructor.static.getImportRules(),
|
||||
inDialog: 'reference',
|
||||
placeholder: ve.msg( 'cite-ve-dialog-reference-placeholder' )
|
||||
}
|
||||
);
|
||||
this.contentFieldset = new OO.ui.FieldsetLayout();
|
||||
this.contentFieldset.$element.append(
|
||||
this.referenceTarget.$element
|
||||
);
|
||||
|
||||
// Create group edit
|
||||
this.optionsFieldset = new OO.ui.FieldsetLayout( {
|
||||
label: ve.msg( 'cite-ve-dialog-reference-options-section' ),
|
||||
icon: 'settings'
|
||||
} );
|
||||
this.referenceGroupInput = new ve.ui.MWReferenceGroupInputWidget( {
|
||||
$overlay: config.$overlay,
|
||||
emptyGroupName: ve.msg( 'cite-ve-dialog-reference-options-group-placeholder' )
|
||||
} );
|
||||
this.referenceGroupField = new OO.ui.FieldLayout( this.referenceGroupInput, {
|
||||
align: 'top',
|
||||
label: ve.msg( 'cite-ve-dialog-reference-options-group-label' )
|
||||
} );
|
||||
this.optionsFieldset.addItems( [ this.referenceGroupField ] );
|
||||
|
||||
// Create warning messages
|
||||
this.reuseWarning = new OO.ui.MessageWidget( {
|
||||
icon: 'alert',
|
||||
inline: true,
|
||||
classes: [ 've-ui-mwReferenceDialog-reuseWarning' ]
|
||||
} );
|
||||
|
||||
this.extendsWarning = new OO.ui.MessageWidget( {
|
||||
icon: 'alert',
|
||||
inline: true,
|
||||
classes: [ 've-ui-mwReferenceDialog-extendsWarning' ]
|
||||
} );
|
||||
|
||||
// Append to panel element
|
||||
this.$element.append(
|
||||
this.reuseWarning.$element,
|
||||
this.extendsWarning.$element,
|
||||
this.contentFieldset.$element,
|
||||
this.optionsFieldset.$element
|
||||
);
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
OO.inheritClass( ve.ui.MWReferenceEditPanel, OO.ui.PanelLayout );
|
||||
|
||||
/* Static Properties */
|
||||
ve.ui.MWReferenceEditPanel.static.excludeCommands = [
|
||||
// No formatting
|
||||
'paragraph',
|
||||
'heading1',
|
||||
'heading2',
|
||||
'heading3',
|
||||
'heading4',
|
||||
'heading5',
|
||||
'heading6',
|
||||
'preformatted',
|
||||
'blockquote',
|
||||
// No tables
|
||||
'insertTable',
|
||||
'deleteTable',
|
||||
'mergeCells',
|
||||
'tableCaption',
|
||||
'tableCellHeader',
|
||||
'tableCellData',
|
||||
// No structure
|
||||
'bullet',
|
||||
'bulletWrapOnce',
|
||||
'number',
|
||||
'numberWrapOnce',
|
||||
'indent',
|
||||
'outdent',
|
||||
// References
|
||||
'reference',
|
||||
'reference/existing',
|
||||
'citoid',
|
||||
'referencesList'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the list of disallowed commands for the surface widget to edit the content. This includes
|
||||
* all Cite related commands to disencourage nesting of references.
|
||||
*
|
||||
* @see ve.dm.ElementLinearData#sanitize
|
||||
* @return {Object} Import rules
|
||||
*/
|
||||
ve.ui.MWReferenceEditPanel.static.getExcludeCommands = function () {
|
||||
const citeCommands = Object.keys( ve.init.target.getSurface().commandRegistry.registry )
|
||||
.filter( ( command ) => command.indexOf( 'cite-' ) !== -1 );
|
||||
|
||||
return ve.ui.MWReferenceEditPanel.static.excludeCommands.concat( citeCommands );
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the import rules for the surface widget to edit the content
|
||||
*
|
||||
* @see ve.dm.ElementLinearData#sanitize
|
||||
* @return {Object} Import rules
|
||||
*/
|
||||
ve.ui.MWReferenceEditPanel.static.getImportRules = function () {
|
||||
const rules = ve.copy( ve.init.target.constructor.static.importRules );
|
||||
return ve.extendObject(
|
||||
rules,
|
||||
{
|
||||
all: {
|
||||
blacklist: ve.extendObject(
|
||||
{
|
||||
// Nested references are impossible
|
||||
mwReference: true,
|
||||
mwReferencesList: true,
|
||||
// Lists and tables are actually possible in wikitext with a leading
|
||||
// line break but we prevent creating these with the UI
|
||||
list: true,
|
||||
listItem: true,
|
||||
definitionList: true,
|
||||
definitionListItem: true,
|
||||
table: true,
|
||||
tableCaption: true,
|
||||
tableSection: true,
|
||||
tableRow: true,
|
||||
tableCell: true,
|
||||
mwTable: true,
|
||||
mwTransclusionTableCell: true
|
||||
},
|
||||
ve.getProp( rules, 'all', 'blacklist' )
|
||||
),
|
||||
// Headings are not possible in wikitext without HTML
|
||||
conversions: ve.extendObject(
|
||||
{
|
||||
mwHeading: 'paragraph'
|
||||
},
|
||||
ve.getProp( rules, 'all', 'conversions' )
|
||||
)
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -5,13 +5,14 @@ QUnit.module( 've.ui.MWReferenceDialog (Cite)', ve.test.utils.newMwEnvironment()
|
|||
QUnit.test( 'setReferenceForEditing', ( assert ) => {
|
||||
const dialog = new ve.ui.MWReferenceDialog();
|
||||
|
||||
dialog.referenceGroupInput = new ve.ui.MWReferenceGroupInputWidget( {} );
|
||||
dialog.reuseWarning = new OO.ui.MessageWidget();
|
||||
dialog.extendsWarning = new OO.ui.MessageWidget();
|
||||
dialog.editPanel = {};
|
||||
dialog.editPanel.referenceGroupInput = new ve.ui.MWReferenceGroupInputWidget( {} );
|
||||
dialog.editPanel.reuseWarning = new OO.ui.MessageWidget();
|
||||
dialog.editPanel.extendsWarning = new OO.ui.MessageWidget();
|
||||
|
||||
// XXX: This is a regression test with a fragile setup. Please feel free to delete this test
|
||||
// when you feel like it doesn't make sense to update it.
|
||||
dialog.referenceTarget = {
|
||||
dialog.editPanel.referenceTarget = {
|
||||
setDocument: () => null
|
||||
};
|
||||
dialog.fragment = {
|
||||
|
@ -31,7 +32,7 @@ QUnit.test( 'setReferenceForEditing', ( assert ) => {
|
|||
|
||||
assert.strictEqual( dialog.referenceModel, ref );
|
||||
assert.strictEqual( dialog.originalGroup, 'g' );
|
||||
assert.strictEqual( dialog.referenceGroupInput.getValue(), 'g' );
|
||||
assert.false( dialog.referenceGroupInput.isDisabled() );
|
||||
assert.false( dialog.reuseWarning.isVisible() );
|
||||
assert.strictEqual( dialog.editPanel.referenceGroupInput.getValue(), 'g' );
|
||||
assert.false( dialog.editPanel.referenceGroupInput.isDisabled() );
|
||||
assert.false( dialog.editPanel.reuseWarning.isVisible() );
|
||||
} );
|
||||
|
|
Loading…
Reference in a new issue