mediawiki-extensions-Visual.../modules/ve-mw/dm/ve.dm.MWWikitextSurfaceFragment.js
Ed Sanders 88e8a9f7a7 Convert empty doc to empty string in convertToSource
Change-Id: I8753169ff206b5ce23cfd4c0dc7f97ac6fd1fff0
2017-11-04 21:16:35 +00:00

184 lines
5 KiB
JavaScript

/*!
* VisualEditor DataModel MWWikitextSurfaceFragment class.
*
* @copyright 2011-2017 VisualEditor Team and others; see http://ve.mit-license.org
*/
/**
* DataModel MWWikitextSurfaceFragment.
*
* @class
* @extends ve.dm.SourceSurfaceFragment
*
* @constructor
* @param {ve.dm.Document} doc
*/
ve.dm.MWWikitextSurfaceFragment = function VeDmMwWikitextSurfaceFragment() {
// Parent constructors
ve.dm.MWWikitextSurfaceFragment.super.apply( this, arguments );
};
/* Inheritance */
OO.inheritClass( ve.dm.MWWikitextSurfaceFragment, ve.dm.SourceSurfaceFragment );
/* Methods */
/**
* @inheritdoc
*/
ve.dm.MWWikitextSurfaceFragment.prototype.hasMatchingAncestor = function ( type, attributes ) {
var i, len, text,
nodes = this.getSelectedLeafNodes(),
all = !!nodes.length;
nodes = this.getSelectedLeafNodes();
all = !!nodes.length;
for ( i = 0, len = nodes.length; i < len; i++ ) {
text = this.document.data.getText( false, nodes[ i ].getRange() );
// TODO: Use a registry to do this matching
switch ( type ) {
case 'paragraph':
all = !text.match( /^ |^=|^<blockquote>/ );
break;
case 'mwPreformatted':
all = text.slice( 0, 1 ) === ' ';
break;
case 'blockquote':
all = text.slice( 0, 12 ) === '<blockquote>';
break;
case 'mwHeading':
all = text.match( new RegExp( '^={' + attributes.level + '}[^=]' ) ) &&
text.match( new RegExp( '[^=]={' + attributes.level + '}$' ) );
break;
default:
all = false;
break;
}
if ( !all ) {
break;
}
}
return all;
};
/**
* Wrap a text selection.
*
* If the selection is already identically wrapped it will be unwrapped.
*
* @param {string} before Text to go before selection
* @param {string} after Text to go after selection
* @param {Function|string} placeholder Placeholder text to insert at an empty selection
* @param {boolean} forceWrap Force wrapping, even if matching wrapping exists
* @chainable
*/
ve.dm.MWWikitextSurfaceFragment.prototype.wrapText = function ( before, after, placeholder, forceWrap ) {
var wrappedFragment, wasExcludingInsertions;
placeholder = OO.ui.resolveMsg( placeholder );
function unwrap( fragment ) {
var text = fragment.getText();
if (
( !before || text.slice( 0, before.length ) === before ) &&
( !after || text.slice( -after.length ) === after )
) {
fragment.unwrapText( before.length, after.length );
// Just the placeholder left, nothing meaningful was selected so just remove it
if ( fragment.getText() === placeholder ) {
fragment.removeContent();
}
return true;
}
return false;
}
if ( !forceWrap && ( unwrap( this ) || unwrap( this.adjustLinearSelection( -before.length, after.length ) ) ) ) {
return this;
} else {
if ( placeholder && this.getSelection().isCollapsed() ) {
this.insertContent( placeholder );
}
wrappedFragment = this.clone();
wasExcludingInsertions = this.willExcludeInsertions();
this.setExcludeInsertions( true );
this.collapseToStart().insertContent( before );
this.collapseToEnd().insertContent( after );
this.setExcludeInsertions( wasExcludingInsertions );
return wrappedFragment;
}
};
/**
* Unwrap a fixed amount of text
*
* @param {number} before Amount of text to remove from start
* @param {number} after Amount of text to remove from end
* @chainable
*/
ve.dm.MWWikitextSurfaceFragment.prototype.unwrapText = function ( before, after ) {
this.collapseToStart().adjustLinearSelection( 0, before ).removeContent();
this.collapseToEnd().adjustLinearSelection( -after, 0 ).removeContent();
return this;
};
/**
* @inheritdoc
*/
ve.dm.MWWikitextSurfaceFragment.prototype.convertToSource = function ( doc ) {
var wikitextPromise;
if ( !doc.data.hasContent() ) {
return $.Deferred().resolve( '' ).promise();
}
wikitextPromise = ve.init.target.getWikitextFragment( doc, false );
// TODO: Emit an event to trigger the progress bar
ve.init.target.getSurface().createProgress(
wikitextPromise, ve.msg( 'visualeditor-generating-wikitext-progress' )
).done( function ( progressBar, cancelPromise ) {
cancelPromise.fail( function () {
wikitextPromise.abort();
} );
} );
return wikitextPromise;
};
/**
* @inheritdoc
*/
ve.dm.MWWikitextSurfaceFragment.prototype.convertFromSource = function ( source ) {
var parsePromise;
if ( !source ) {
parsePromise = $.Deferred().resolve(
ve.dm.Document.static.newBlankDocument()
).promise();
} else {
parsePromise = new mw.Api().post( {
action: 'visualeditor',
paction: 'parsefragment',
page: ve.init.target.pageName,
wikitext: source
} ).then( function ( response ) {
return ve.dm.converter.getModelFromDom(
ve.createDocumentFromHtml( response.visualeditor.content )
);
} );
}
// TODO: Show progress bar without breaking WindowAction
// ve.init.target.getSurface().createProgress(
// parsePromise, ve.msg( 'visualeditor-generating-wikitext-progress' )
// ).done( function ( progressBar, cancelPromise ) {
// cancelPromise.fail( function () {
// parsePromise.abort();
// } );
// } );
return parsePromise;
};