mediawiki-extensions-Math/modules/ve-math/ve.ui.MWMathDialog.js
Thalia 3f193f6745 Make math dialog menu content scrollable
Also make input widget height respond to its contents. These two
changes address the problems of overlapping when the screen
height is limited.

Bug: T119900
Change-Id: Ie21c141673a9343d05da05cdbd2eaa96efff0a58
2015-12-03 16:25:00 +00:00

295 lines
7.2 KiB
JavaScript

/*!
* VisualEditor user interface MWMathDialog class.
*
* @copyright 2015 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Dialog for inserting and editing formulas.
*
* @class
* @extends ve.ui.MWExtensionDialog
*
* @constructor
* @param {Object} [config] Configuration options
*/
ve.ui.MWMathDialog = function VeUiMWMathDialog( config ) {
// Parent constructor
ve.ui.MWMathDialog.super.call( this, config );
};
/* Inheritance */
OO.inheritClass( ve.ui.MWMathDialog, ve.ui.MWExtensionPreviewDialog );
/* Static properties */
ve.ui.MWMathDialog.static.name = 'math';
ve.ui.MWMathDialog.static.icon = 'math';
ve.ui.MWMathDialog.static.title = OO.ui.deferMsg( 'math-visualeditor-mwmathdialog-title' );
ve.ui.MWMathDialog.static.size = 'larger';
ve.ui.MWMathDialog.static.modelClasses = [ ve.dm.MWMathNode ];
ve.ui.MWMathDialog.static.dir = 'ltr';
ve.ui.MWMathDialog.static.symbols = null;
/* static methods */
/**
* Set the symbols property
*
* @param {Object} symbols The math symbols and their group names
*/
ve.ui.MWMathDialog.static.setSymbols = function ( symbols ) {
this.symbols = symbols;
};
/* Methods */
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.initialize = function () {
var formulaPanel, inputField, displayField, idField, category,
formulaCard, optionsCard,
dialog = this;
// Parent method
ve.ui.MWMathDialog.super.prototype.initialize.call( this );
// Layout for the formula inserter (formula card) and options form (options card)
this.indexLayout = new OO.ui.IndexLayout( {
scrollable: false,
expanded: true
} );
formulaCard = new OO.ui.CardLayout( 'formula', {
label: ve.msg( 'math-visualeditor-mwmathdialog-card-formula' ),
expandable: false,
scrollable: false,
padded: true
} );
optionsCard = new OO.ui.CardLayout( 'options', {
label: ve.msg( 'math-visualeditor-mwmathdialog-card-options' ),
expandable: false,
scrollable: false,
padded: true
} );
this.indexLayout.addCards( [
formulaCard,
optionsCard
] );
// Layout for symbol picker (menu) and input and preview (content)
this.menuLayout = new OO.ui.MenuLayout( {
menuPosition: 'bottom',
classes: [ 've-ui-mwMathDialog-menuLayout' ]
} );
this.previewElement.$element.addClass(
've-ui-mwMathDialog-preview'
);
this.input = new ve.ui.MWAceEditorWidget( {
multiline: true,
autosize: true,
maxRows: 7,
autocomplete: 'live'
} ).setLanguage( 'latex' );
this.input.togglePrintMargin( false );
this.displaySelect = new OO.ui.ButtonSelectWidget( {
items: [
new OO.ui.ButtonOptionWidget( {
data: 'default',
icon: 'math-display-default',
label: ve.msg( 'math-visualeditor-mwmathinspector-display-default' )
} ),
new OO.ui.ButtonOptionWidget( {
data: 'inline',
icon: 'math-display-inline',
label: ve.msg( 'math-visualeditor-mwmathinspector-display-inline' )
} ),
new OO.ui.ButtonOptionWidget( {
data: 'block',
icon: 'math-display-block',
label: ve.msg( 'math-visualeditor-mwmathinspector-display-block' )
} )
]
} );
this.idInput = new OO.ui.TextInputWidget();
inputField = new OO.ui.FieldLayout( this.input, {
align: 'top',
label: ve.msg( 'math-visualeditor-mwmathinspector-title' )
} );
displayField = new OO.ui.FieldLayout( this.displaySelect, {
align: 'top',
label: ve.msg( 'math-visualeditor-mwmathinspector-display' )
} );
idField = new OO.ui.FieldLayout( this.idInput, {
align: 'top',
label: ve.msg( 'math-visualeditor-mwmathinspector-id' )
} );
formulaPanel = new OO.ui.PanelLayout( {
padded: true
} );
// Layout for the symbol picker
this.bookletLayout = new OO.ui.BookletLayout( {
menuPosition: 'before',
outlined: true,
continuous: true
} );
this.pages = [];
this.symbolsPromise = mw.loader.using( 'ext.math.visualEditor.symbols' ).done( function () {
var symbols = dialog.constructor.static.symbols;
for ( category in symbols ) {
dialog.pages.push(
new ve.ui.MWMathPage( ve.msg( category ), {
label: ve.msg( category ),
symbols: symbols[ category ]
} )
);
}
dialog.bookletLayout.addPages( dialog.pages );
dialog.bookletLayout.$element.on(
'click',
'.ve-ui-mwMathPage-symbol',
dialog.onListClick.bind( dialog )
);
// Append everything
dialog.menuLayout.$menu.append(
dialog.bookletLayout.$element
);
dialog.menuLayout.$content.append(
formulaPanel.$element.append(
dialog.previewElement.$element,
inputField.$element
)
);
formulaCard.$element.append(
dialog.menuLayout.$element
);
optionsCard.$element.append(
displayField.$element,
idField.$element
);
dialog.$body
.addClass( 've-ui-mwMathDialog-content' )
.append( dialog.indexLayout.$element );
} );
};
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWMathDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var attributes = this.selectedNode && this.selectedNode.getAttribute( 'mw' ).attrs,
display = attributes && attributes.display || 'default',
id = attributes && attributes.id || '';
// Populate form
this.displaySelect.selectItemByData( display );
this.idInput.setValue( id );
// Add event handlers
this.input.on( 'change', this.onChangeHandler );
this.displaySelect.on( 'choose', this.onChangeHandler );
this.idInput.on( 'change', this.onChangeHandler );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.getReadyProcess = function ( data ) {
return ve.ui.MWMathDialog.super.prototype.getReadyProcess.call( this, data )
.next( function () {
this.input.focus().moveCursorToEnd();
return this.symbolsPromise;
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWMathDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
this.input.off( 'change', this.onChangeHandler );
this.displaySelect.off( 'choose', this.onChangeHandler );
this.idInput.off( 'change', this.onChangeHandler );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.updateMwData = function ( mwData ) {
var display, id;
// Parent method
ve.ui.MWMathDialog.super.prototype.updateMwData.call( this, mwData );
// Get data from dialog
display = this.displaySelect.getSelectedItem().getData();
id = this.idInput.getValue();
// Update attributes
mwData.attrs.display = display !== 'default' ? display : undefined;
mwData.attrs.id = id || undefined;
};
/**
* @inheritdoc
*/
ve.ui.MWMathDialog.prototype.getBodyHeight = function () {
return 600;
};
/**
* Handle the click event on the list
*
* @param {jQuery.Event} e Mouse click event
*/
ve.ui.MWMathDialog.prototype.onListClick = function ( e ) {
var symbol = $( e.target ).data( 'symbol' ),
encapsulate = symbol.encapsulate,
insert = symbol.insert,
range = this.input.getRange();
if ( encapsulate ) {
if ( range.from === range.to ) {
this.input.insertContent( encapsulate.placeholder );
this.input.selectRange( range.from, range.from + encapsulate.placeholder.length );
}
this.input.encapsulateContent( encapsulate.pre, encapsulate.post );
} else {
this.input.insertContent( insert );
}
};
/* Registration */
ve.ui.windowFactory.register( ve.ui.MWMathDialog );