mediawiki-extensions-Visual.../modules/ve-mw/ui/dialogs/ve.ui.MWExtensionPreviewDialog.js
Thalia 43c2865f90 Update actions on live inspectors and preview dialogs
Make inspectors inheriting from MWLiveExtensionInspector
and dialogs inheriting from MWExtensionPreviewDialog
update their 'done' action every time updatePreview is
called. Since both mix in ExtensionWindow, two new methods,
updateActions and isModified are added there.

This should make it more difficult to insert an empty node
accidentally or create a transaction just by opening and
closing an inspector or dialog.

For more complicated dialogs, or inspectors or dialogs
that don't live-update, this behaviour will have to be
implemented separately.

Bug: T155330
Change-Id: Iacafa01fcd419faaec9b112c96be86693a57d561
2017-01-21 18:29:18 +00:00

100 lines
2.7 KiB
JavaScript

/*!
* VisualEditor UserInterface MWExtensionPreviewDialog class.
*
* @copyright 2011-2017 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Dialog for editing generic MediaWiki extensions with a preview.
*
* @class
* @abstract
* @extends ve.ui.MWExtensionDialog
*
* @constructor
* @param {Object} [config] Configuration options
*/
ve.ui.MWExtensionPreviewDialog = function VeUiMWExtensionPreviewDialog() {
// Parent constructor
ve.ui.MWExtensionPreviewDialog.super.apply( this, arguments );
this.updatePreviewDebounced = ve.debounce( this.updatePreview.bind( this ), 250 );
};
/* Inheritance */
OO.inheritClass( ve.ui.MWExtensionPreviewDialog, ve.ui.MWExtensionDialog );
/* Methods */
/**
* @inheritdoc
*/
ve.ui.MWExtensionPreviewDialog.prototype.initialize = function () {
// Parent method
ve.ui.MWExtensionPreviewDialog.super.prototype.initialize.call( this );
// Properties
this.previewNode = null;
this.previewElement = new ve.ui.MWPreviewElement();
// Initialization
this.$element.addClass( 've-ui-mwExtensionPreviewDialog' );
};
/**
* @inheritdoc
*/
ve.ui.MWExtensionPreviewDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWExtensionPreviewDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var doc, element, rootNode, linearData;
if ( this.selectedNode ) {
element = this.selectedNode.getClonedElement();
} else {
element = this.getNewElement();
}
linearData = [ element, { type: '/' + element.type } ];
if ( ve.dm.nodeFactory.isNodeContent( element.type ) ) {
linearData = [ { type: 'paragraph' } ].concat( linearData, { type: '/paragraph' } );
}
// We assume that WindowAction pass
doc = data.fragment.getDocument().cloneWithData( linearData.concat( [
{ type: 'internalList' },
{ type: '/internalList' }
] ) );
rootNode = doc.getDocumentNode().children[ 0 ];
this.previewNode = doc.getNodesByType( element.type )[ 0 ];
this.previewElement.setModel( rootNode );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWExtensionPreviewDialog.prototype.onChange = function () {
// Parent method
ve.ui.MWExtensionPreviewDialog.super.prototype.onChange.call( this );
this.updatePreviewDebounced();
};
/**
* Update the node rendering to reflect the current content in the dialog.
*/
ve.ui.MWExtensionPreviewDialog.prototype.updatePreview = function () {
var mwData = ve.copy( this.previewNode.getAttribute( 'mw' ) ),
doc = this.previewNode.getDocument();
this.updateMwData( mwData );
doc.commit(
ve.dm.TransactionBuilder.static.newFromAttributeChanges(
doc, this.previewNode.getOuterRange().start, { mw: mwData }
)
);
this.previewElement.updatePreview();
};