mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Cite
synced 2024-12-18 09:40:49 +00:00
3af9dfdb71
Making sure that change events form the fields are handled in the panel and forwarded to the dialog with the information needed. Also slighly moving some calls in the setup process that inits the dialog and removing some duplication. Calling focus on the edit panel only makes sense in the ready step. Not during setup. Bug: T369005 Change-Id: I4f9a022a06ec6543b106620eae030235b8f6712b
252 lines
7 KiB
JavaScript
252 lines
7 KiB
JavaScript
'use strict';
|
|
|
|
/*!
|
|
* VisualEditor UserInterface MediaWiki MWReferenceDialog class.
|
|
*
|
|
* @copyright 2011-2018 VisualEditor Team's Cite sub-team and others; see AUTHORS.txt
|
|
* @license MIT
|
|
*/
|
|
|
|
/**
|
|
* Dialog for inserting, editing and re-using MediaWiki references.
|
|
*
|
|
* @constructor
|
|
* @extends ve.ui.NodeDialog
|
|
* @param {Object} [config] Configuration options
|
|
*/
|
|
ve.ui.MWReferenceDialog = function VeUiMWReferenceDialog( config ) {
|
|
// Parent constructor
|
|
ve.ui.MWReferenceDialog.super.call( this, config );
|
|
|
|
// Properties
|
|
this.referenceModel = null;
|
|
this.reuseReference = false;
|
|
};
|
|
|
|
/* Inheritance */
|
|
|
|
OO.inheritClass( ve.ui.MWReferenceDialog, ve.ui.NodeDialog );
|
|
|
|
/* Static Properties */
|
|
|
|
ve.ui.MWReferenceDialog.static.name = 'reference';
|
|
|
|
ve.ui.MWReferenceDialog.static.title =
|
|
OO.ui.deferMsg( 'cite-ve-dialog-reference-title' );
|
|
|
|
ve.ui.MWReferenceDialog.static.actions = [
|
|
{
|
|
action: 'done',
|
|
label: OO.ui.deferMsg( 'visualeditor-dialog-action-apply' ),
|
|
flags: [ 'progressive', 'primary' ],
|
|
modes: 'edit'
|
|
},
|
|
{
|
|
action: 'insert',
|
|
label: OO.ui.deferMsg( 'visualeditor-dialog-action-insert' ),
|
|
flags: [ 'progressive', 'primary' ],
|
|
modes: 'insert'
|
|
},
|
|
{
|
|
label: OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ),
|
|
flags: [ 'safe', 'close' ],
|
|
modes: [ 'readonly', 'insert', 'edit', 'insert-select' ]
|
|
}
|
|
];
|
|
|
|
ve.ui.MWReferenceDialog.static.modelClasses = [ ve.dm.MWReferenceNode ];
|
|
|
|
/* Methods */
|
|
/**
|
|
* Handle ve.ui.MWReferenceEditPanel#change events
|
|
*
|
|
* @param {Object} change
|
|
* @param {boolean} [change.isModified] If changes to the original content or values have been made
|
|
* @param {boolean} [change.hasContent] If there's non empty content set
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.onEditPanelInputChange = function ( change ) {
|
|
this.actions.setAbilities( {
|
|
done: change.isModified,
|
|
insert: change.hasContent
|
|
} );
|
|
|
|
if ( !this.trackedInputChange ) {
|
|
ve.track( 'activity.' + this.constructor.static.name, { action: 'input' } );
|
|
this.trackedInputChange = true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle search results choose events.
|
|
*
|
|
* @param {ve.ui.MWReferenceResultWidget} item Chosen item
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.onReuseSearchResultsChoose = function ( item ) {
|
|
const ref = item.getData();
|
|
|
|
if ( this.selectedNode instanceof ve.dm.MWReferenceNode ) {
|
|
this.getFragment().removeContent();
|
|
this.selectedNode = null;
|
|
}
|
|
|
|
this.insertReference( ref );
|
|
|
|
ve.track( 'activity.' + this.constructor.static.name, { action: 'reuse-choose' } );
|
|
|
|
this.close( { action: 'insert' } );
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.getReadyProcess = function ( data ) {
|
|
return ve.ui.MWReferenceDialog.super.prototype.getReadyProcess.call( this, data )
|
|
.next( () => {
|
|
if ( this.reuseReference ) {
|
|
this.reuseSearch.getQuery().focus().select();
|
|
} else {
|
|
this.editPanel.focus();
|
|
}
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.getBodyHeight = function () {
|
|
// Clamp value to between 300 and 400px height, preferring the actual height if available
|
|
return Math.min(
|
|
400,
|
|
Math.max(
|
|
300,
|
|
Math.ceil( this.panels.getCurrentItem().$element[ 0 ].scrollHeight )
|
|
)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.initialize = function () {
|
|
// Parent method
|
|
ve.ui.MWReferenceDialog.super.prototype.initialize.call( this );
|
|
|
|
// Properties
|
|
this.panels = new OO.ui.StackLayout();
|
|
this.editPanel = new ve.ui.MWReferenceEditPanel( { $overlay: this.$overlay } );
|
|
this.reuseSearchPanel = new OO.ui.PanelLayout();
|
|
|
|
this.reuseSearch = new ve.ui.MWReferenceSearchWidget();
|
|
|
|
// Events
|
|
this.reuseSearch.getResults().connect( this, { choose: 'onReuseSearchResultsChoose' } );
|
|
this.editPanel.connect( this, { change: 'onEditPanelInputChange' } );
|
|
|
|
// Initialization
|
|
this.$content.addClass( 've-ui-mwReferenceDialog' );
|
|
|
|
this.panels.addItems( [ this.editPanel, this.reuseSearchPanel ] );
|
|
this.reuseSearchPanel.$element.append( this.reuseSearch.$element );
|
|
this.$body.append( this.panels.$element );
|
|
};
|
|
|
|
/**
|
|
* Switches dialog to use existing reference mode.
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.openReusePanel = function () {
|
|
this.actions.setMode( 'insert-select' );
|
|
this.reuseSearch.buildIndex();
|
|
this.panels.setItem( this.reuseSearchPanel );
|
|
|
|
// https://phabricator.wikimedia.org/T362347
|
|
ve.track( 'activity.' + this.constructor.static.name, { action: 'dialog-open-reuse' } );
|
|
};
|
|
|
|
/**
|
|
* Insert a reference at the end of the selection, could also be a reuse of an exising reference
|
|
*
|
|
* @private
|
|
* @param {ve.dm.MWReferenceModel} ref
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.insertReference = function ( ref ) {
|
|
const surfaceModel = this.getFragment().getSurface();
|
|
|
|
if ( !ref.findInternalItem( surfaceModel ) ) {
|
|
ref.insertInternalItem( surfaceModel );
|
|
}
|
|
// Collapse returns a new fragment, so update this.fragment
|
|
this.fragment = this.getFragment().collapseToEnd();
|
|
ref.insertReferenceNode( this.getFragment() );
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.getActionProcess = function ( action ) {
|
|
if ( action === 'insert' || action === 'done' ) {
|
|
return new OO.ui.Process( () => {
|
|
this.referenceModel = this.editPanel.getReferenceFromEditing();
|
|
|
|
if ( !( this.selectedNode instanceof ve.dm.MWReferenceNode ) ) {
|
|
this.insertReference( this.referenceModel );
|
|
}
|
|
|
|
this.referenceModel.updateInternalItem( this.getFragment().getSurface() );
|
|
|
|
this.close( { action: action } );
|
|
} );
|
|
}
|
|
return ve.ui.MWReferenceDialog.super.prototype.getActionProcess.call( this, action );
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
* @param {Object} [data] Setup data
|
|
* @param {boolean} [data.reuseReference=false] Open the dialog in "use existing reference" mode
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.getSetupProcess = function ( data ) {
|
|
data = data || {};
|
|
return ve.ui.MWReferenceDialog.super.prototype.getSetupProcess.call( this, data )
|
|
.next( () => {
|
|
this.panels.setItem( this.editPanel );
|
|
this.editPanel.setInternalList( this.getFragment().getDocument().getInternalList() );
|
|
this.actions.setAbilities( { done: false } );
|
|
|
|
if ( this.selectedNode instanceof ve.dm.MWReferenceNode ) {
|
|
// edit an existing reference
|
|
this.referenceModel = ve.dm.MWReferenceModel.static.newFromReferenceNode( this.selectedNode );
|
|
} else {
|
|
// create a new reference
|
|
this.referenceModel = new ve.dm.MWReferenceModel( this.getFragment().getDocument() );
|
|
this.actions.setAbilities( { insert: false } );
|
|
}
|
|
this.editPanel.setReferenceForEditing( this.referenceModel );
|
|
this.editPanel.setReadOnly( this.isReadOnly() );
|
|
|
|
this.reuseSearch.setInternalList( this.getFragment().getDocument().getInternalList() );
|
|
|
|
this.reuseReference = !!data.reuseReference;
|
|
if ( this.reuseReference ) {
|
|
this.openReusePanel();
|
|
}
|
|
|
|
this.trackedInputChange = false;
|
|
} );
|
|
};
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ve.ui.MWReferenceDialog.prototype.getTeardownProcess = function ( data ) {
|
|
return ve.ui.MWReferenceDialog.super.prototype.getTeardownProcess.call( this, data )
|
|
.first( () => {
|
|
this.editPanel.clear();
|
|
this.reuseSearch.clearSearch();
|
|
this.referenceModel = null;
|
|
} );
|
|
};
|
|
|
|
/* Registration */
|
|
|
|
ve.ui.windowFactory.register( ve.ui.MWReferenceDialog );
|