mediawiki-extensions-Visual.../modules/ve-mw/ui/datatransferhandlers/ve.ui.MWWikitextStringTransferHandler.js
C. Scott Ananian 7cc23367f6 Specialized inspector for ISBN magic links
Implement a special node type, context item, and inspector for
ISBN/PMID/RFC magic links.  Add buttons to the link inspectors
to convert back and forth between "simple" links, and magic links.

Depends on I5d000d8b63dafdfe0a2753069d3f0ac5b03b8829 in Parsoid
for clean round-tripping of localized ISBN magic links.

Bug: T63558
Change-Id: Id5b7a2ae3c80b0e5eed598f0bd024d3e94f7e9aa
2015-09-01 14:25:59 -04:00

143 lines
4 KiB
JavaScript

/*!
* VisualEditor UserInterface MWWikitextStringTransferHandler class.
*
* @copyright 2011-2015 VisualEditor Team and others; see http://ve.mit-license.org
*/
/**
* Detect an attempt to paste wikitext, and convert it to proper
* HTML.
*
* @class
* @extends ve.ui.PlainTextStringTransferHandler
*
* @constructor
* @param {ve.ui.Surface} surface
* @param {ve.ui.DataTransferItem} item
*/
ve.ui.MWWikitextStringTransferHandler = function VeUiMWWikitextStringTransferHandler() {
// Parent constructor
ve.ui.MWWikitextStringTransferHandler.super.apply( this, arguments );
// Properties
this.parsoidRequest = null;
};
/* Inheritance */
OO.inheritClass( ve.ui.MWWikitextStringTransferHandler, ve.ui.PlainTextStringTransferHandler );
/* Static properties */
ve.ui.MWWikitextStringTransferHandler.static.name = 'wikitextString';
ve.ui.MWWikitextStringTransferHandler.static.types =
ve.ui.MWWikitextStringTransferHandler.super.static.types.concat(
[ 'text/x-wiki' ]
);
ve.ui.MWWikitextStringTransferHandler.static.handlesPaste = true;
/**
* Heuristic pattern which attempts to discover wikitext, without
* incurring too many false positives.
*
* Currently the pattern looks for ==...==, [[...]], or {{...}}
* which occur on a single line of max 80 characters.
*/
ve.ui.MWWikitextStringTransferHandler.static.matchRegExp =
/(^\s*(={2,6})[^=\r\n]{1,80}\2\s*$)|\[\[.{1,80}\]\]|\{\{.{1,80}\}\}/m;
ve.ui.MWWikitextStringTransferHandler.static.matchFunction = function ( item ) {
var text = item.getAsString();
// If the mime type is explicitly wikitext (ie, not plain text),
// always accept.
if ( item.type === 'text/x-wiki' ) {
return true;
}
// Detect autolink opportunities for magic words.
// (The link should be the only contents of paste to match this heuristic)
if ( ve.dm.MWMagicLinkNode.static.validateContent( text.trim() ) ) {
return true;
}
// Use a heuristic regexp to find text likely to be wikitext.
// This test could be made more sophisticated in the future.
if ( this.matchRegExp.test( text ) ) {
return true;
}
return false;
};
/* Methods */
/**
* @inheritdoc
*/
ve.ui.MWWikitextStringTransferHandler.prototype.process = function () {
var handler = this,
wikitext = this.item.getAsString();
function failure() {
// There's no DTH fallback handling for failures, so just paste
// the raw wikitext if things go wrong.
handler.resolve( wikitext );
}
// Convert wikitext to html using Parsoid.
this.parsoidRequest = new mw.Api().post( {
action: 'visualeditor',
paction: 'parsefragment',
page: mw.config.get( 'wgRelevantPageName' ),
wikitext: wikitext
} );
// Don't immediately chain, as this.parsoidRequest must be abortable
this.parsoidRequest.then( function ( response ) {
var doc, surface;
if ( ve.getProp( response, 'visualeditor', 'result' ) !== 'success' ) {
return failure();
}
doc = handler.surface.getModel().getDocument().newFromHtml(
response.visualeditor.content,
null // No sanitization, since HTML is from Parsoid
);
// Attempt to undo outermost p-wrapping if possible
surface = new ve.dm.Surface( doc );
try {
surface.change(
ve.dm.Transaction.newFromWrap( doc, new ve.Range( 0, doc.data.countNonInternalElements() ), [], [], [ { type: 'paragraph' } ], [] )
);
} catch ( e ) {
// Sometimes there is no p-wrapping, for example: "* foo"
// Sometimes there are multiple <p> tags in the output.
// That's okay: ignore the error and paste what we've got.
}
handler.resolve( doc );
}, failure );
this.createProgress( this.parsoidRequest, ve.msg( 'visualeditor-wikitext-progress' ) );
// Indeterminate progress
this.setProgress( null );
};
/**
* @inheritdoc
*/
ve.ui.MWWikitextStringTransferHandler.prototype.abort = function () {
// Parent method
ve.ui.MWWikitextStringTransferHandler.super.prototype.abort.apply( this, arguments );
if ( this.parsoidRequest ) {
this.parsoidRequest.abort();
}
};
/* Registration */
ve.ui.dataTransferHandlerFactory.register( ve.ui.MWWikitextStringTransferHandler );