mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-26 07:15:32 +00:00
12e4b41660
The setup method just assumed this.node was of the right type, and would just crash if it wasn't. You could select an image, open the gallery inspector, and it would happily try to inspect it until crashing because there was no .mw.extsrc attribute. Bug: 60502 Change-Id: Idf0e9cf7ccaa37e607374ced150db732926a19f8
136 lines
3.4 KiB
JavaScript
136 lines
3.4 KiB
JavaScript
/*!
|
|
* VisualEditor UserInterface MWExtensionInspector class.
|
|
*
|
|
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* MediaWiki extension inspector.
|
|
*
|
|
* @class
|
|
* @abstract
|
|
* @extends ve.ui.Inspector
|
|
*
|
|
* @constructor
|
|
* @param {ve.ui.WindowSet} windowSet Window set this inspector is part of
|
|
* @param {Object} [config] Configuration options
|
|
*/
|
|
ve.ui.MWExtensionInspector = function VeUiMWExtensionInspector( windowSet, config ) {
|
|
// Parent constructor
|
|
ve.ui.Inspector.call( this, windowSet, config );
|
|
};
|
|
|
|
/* Inheritance */
|
|
|
|
OO.inheritClass( ve.ui.MWExtensionInspector, ve.ui.Inspector );
|
|
|
|
/* Static properties */
|
|
|
|
ve.ui.MWExtensionInspector.static.nodeView = null;
|
|
|
|
ve.ui.MWExtensionInspector.static.nodeModel = null;
|
|
|
|
ve.ui.MWExtensionInspector.static.removable = false;
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* Handle frame ready events.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ui.MWExtensionInspector.prototype.initialize = function () {
|
|
// Parent method
|
|
ve.ui.Inspector.prototype.initialize.call( this );
|
|
|
|
this.input = new OO.ui.TextInputWidget( {
|
|
'$': this.$,
|
|
'overlay': this.surface.$localOverlay,
|
|
'multiline': true
|
|
} );
|
|
this.input.$element.addClass( 've-ui-mwExtensionInspector-input' );
|
|
|
|
// Initialization
|
|
this.$form.append( this.input.$element );
|
|
};
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.ui.MWExtensionInspector.prototype.setup = function ( data ) {
|
|
var dir,
|
|
fragment = this.surface.getModel().getFragment( null, true );
|
|
|
|
// Parent method
|
|
ve.ui.Inspector.prototype.setup.call( this, data );
|
|
|
|
// Initialization
|
|
this.node = this.surface.getView().getFocusedNode();
|
|
// Make sure we're inspecting the right type of node
|
|
if ( !( this.node instanceof this.constructor.static.nodeView ) ) {
|
|
this.node = null;
|
|
}
|
|
this.input.setValue( this.node ? this.node.getModel().getAttribute( 'mw' ).body.extsrc : '' );
|
|
|
|
// By default, the direction of the input element should be the same
|
|
// as the direction of the content it applies to
|
|
if ( this.node ) {
|
|
// The node is being edited
|
|
dir = this.node.$element.css( 'direction' );
|
|
} else {
|
|
// New insertion, base direction on the fragment range
|
|
dir = this.surface.getView().documentView.getDirectionFromRange( fragment.getRange() );
|
|
}
|
|
this.input.setRTL( dir === 'rtl' );
|
|
};
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.ui.MWExtensionInspector.prototype.ready = function () {
|
|
// Parent method
|
|
ve.ui.Inspector.prototype.ready.call( this );
|
|
|
|
// Focus the input
|
|
this.input.$input.focus().select();
|
|
};
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.ui.MWExtensionInspector.prototype.teardown = function ( data ) {
|
|
var mwData,
|
|
surfaceModel = this.surface.getModel();
|
|
|
|
if ( this.node instanceof this.constructor.static.nodeView ) {
|
|
mwData = ve.copy( this.node.getModel().getAttribute( 'mw' ) );
|
|
mwData.body.extsrc = this.input.getValue();
|
|
surfaceModel.change(
|
|
ve.dm.Transaction.newFromAttributeChanges(
|
|
surfaceModel.getDocument(), this.node.getOuterRange().start, { 'mw': mwData }
|
|
)
|
|
);
|
|
} else {
|
|
mwData = {
|
|
'name': this.constructor.static.nodeModel.static.extensionName,
|
|
'attrs': {},
|
|
'body': {
|
|
'extsrc': this.input.getValue()
|
|
}
|
|
};
|
|
surfaceModel.getFragment().collapseRangeToEnd().insertContent( [
|
|
{
|
|
'type': this.constructor.static.nodeModel.static.name,
|
|
'attributes': {
|
|
'mw': mwData
|
|
}
|
|
},
|
|
{ 'type': '/' + this.constructor.static.nodeModel.static.name }
|
|
] );
|
|
}
|
|
|
|
// Parent method
|
|
ve.ui.Inspector.prototype.teardown.call( this, data );
|
|
};
|