jenkins-bot has submitted this change and it was merged.
Change subject: Autolink typed ISBN/RFC/PMIDs
......................................................................
Autolink typed ISBN/RFC/PMIDs
Depends on Ibdad2fa98fca08eeaa96bf33a08dd7723c1edb8c in Parsoid.
Depends on I3dcd289ed7b565b9162ee671038eeb45449e1215 in ve-core.
Bug: T109498
Change-Id: I5650410d7fca30c90baddd4f0c3f6d80e6b39042
---
M modules/ve-mw/tests/ui/actions/ve.ui.MWLinkAction.test.js
M modules/ve-mw/ui/actions/ve.ui.MWLinkAction.js
2 files changed, 139 insertions(+), 14 deletions(-)
Approvals:
Jforrester: Looks good to me, but someone else must approve
Esanders: Looks good to me, approved
jenkins-bot: Verified
diff --git a/modules/ve-mw/tests/ui/actions/ve.ui.MWLinkAction.test.js
b/modules/ve-mw/tests/ui/actions/ve.ui.MWLinkAction.test.js
index eea42bd..ba60cc3 100644
--- a/modules/ve-mw/tests/ui/actions/ve.ui.MWLinkAction.test.js
+++ b/modules/ve-mw/tests/ui/actions/ve.ui.MWLinkAction.test.js
@@ -10,14 +10,17 @@
/* Tests */
function runMWAutolinkTest( assert, html, method, range, expectedRange,
expectedData, expectedOriginalData, msg ) {
- var status,
+ var status, actualData,
expectFail = /^Don't/.test( msg ),
surface = ve.test.utils.createModelOnlySurfaceFromHtml( html ||
ve.dm.example.html ),
linkAction = new ve.ui.MWLinkAction( surface ),
data = ve.copy( surface.getModel().getDocument().getFullData()
),
- originalData = ve.copy( data );
+ originalData = ve.copy( data ),
+ makeLinkAnnotation = function ( linktext ) {
+ return linkAction.getLinkAnnotation( linktext ).element;
+ };
- expectedData( data );
+ expectedData( data, makeLinkAnnotation );
if ( expectedOriginalData ) {
expectedOriginalData( originalData );
}
@@ -25,7 +28,9 @@
status = linkAction[ method ]();
assert.equal( status, !expectFail, msg + ': action return value' );
- assert.equalLinearData( surface.getModel().getDocument().getFullData(),
data, msg + ': data models match' );
+ actualData = surface.getModel().getDocument().getFullData();
+ ve.dm.example.postprocessAnnotations( actualData,
surface.getModel().getDocument().getStore() );
+ assert.equalLinearData( actualData, data, msg + ': data models match' );
assert.equalRange( surface.getModel().getSelection().getRange(),
expectedRange, msg + ': ranges match' );
if ( status ) {
@@ -40,17 +45,90 @@
var i,
cases = [
{
+ msg: 'Strip trailing punctuation (but not
matched parens)',
html:
'<p>https://en.wikipedia.org/wiki/Red_(disambiguation) xyz</p>',
range: new ve.Range( 1, 52 ),
method: 'autolinkUrl',
expectedRange: new ve.Range( 52, 52 ),
- expectedData: function ( data ) {
- var i;
+ expectedData: function ( data, makeAnnotation )
{
+ var i,
+ a = makeAnnotation(
'https://en.wikipedia.org/wiki/Red_(disambiguation)' );
for ( i = 1; i < 51; i++ ) {
- data[ i ] = [ data[ i ], [ 0 ]
];
+ data[ i ] = [ data[ i ], [ a ]
];
}
- },
- msg: 'Strip trailing punctuation (but not
matched parens)'
+ }
+ },
+ {
+ msg: 'Autolink valid RFC',
+ html: '<p>RFC 1234 xyz</p>',
+ range: new ve.Range( 1, 10 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 10, 10 ),
+ expectedData: function ( data, makeAnnotation )
{
+ var i,
+ a = makeAnnotation(
'//tools.ietf.org/html/rfc1234' );
+ for ( i = 1; i < 9; i++ ) {
+ data[ i ] = [ data[ i ], [ a ]
];
+ }
+ }
+ },
+ {
+ msg: 'Don\'t autolink invalid RFC',
+ html: '<p>RFC 123x xyz</p>',
+ range: new ve.Range( 1, 10 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 1, 10 ),
+ expectedData: function ( /*data,
makeAnnotation*/ ) {
+ /* no change, no link */
+ }
+ },
+ {
+ msg: 'Autolink valid PMID',
+ html: '<p>PMID 1234 xyz</p>',
+ range: new ve.Range( 1, 11 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 11, 11 ),
+ expectedData: function ( data, makeAnnotation )
{
+ var i,
+ a = makeAnnotation(
'//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract' );
+ for ( i = 1; i < 10; i++ ) {
+ data[ i ] = [ data[ i ], [ a ]
];
+ }
+ }
+ },
+ {
+ msg: 'Don\'t autolink invalid PMID',
+ html: '<p>PMID 123x xyz</p>',
+ range: new ve.Range( 1, 11 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 1, 11 ),
+ expectedData: function ( /*data,
makeAnnotation*/ ) {
+ /* no change, no link */
+ }
+ },
+ {
+ msg: 'Autolink valid ISBN',
+ html: '<p>ISBN 978-0596517748 xyz</p>',
+ range: new ve.Range( 1, 21 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 21, 21 ),
+ expectedData: function ( data, makeAnnotation )
{
+ var i,
+ a = makeAnnotation(
'./Special:BookSources/9780596517748' );
+ for ( i = 1; i < 20; i++ ) {
+ data[ i ] = [ data[ i ], [ a ]
];
+ }
+ }
+ },
+ {
+ msg: 'Don\'t autolink invalid ISBN',
+ html: '<p>ISBN 978-059651774 xyz</p>',
+ range: new ve.Range( 1, 20 ),
+ method: 'autolinkMagicLink',
+ expectedRange: new ve.Range( 1, 20 ),
+ expectedData: function ( /*data,
makeAnnotation*/ ) {
+ /* no change, no link */
+ }
}
];
diff --git a/modules/ve-mw/ui/actions/ve.ui.MWLinkAction.js
b/modules/ve-mw/ui/actions/ve.ui.MWLinkAction.js
index 5bf915f..62acfa8 100644
--- a/modules/ve-mw/ui/actions/ve.ui.MWLinkAction.js
+++ b/modules/ve-mw/ui/actions/ve.ui.MWLinkAction.js
@@ -31,7 +31,7 @@
* @static
* @property
*/
-ve.ui.MWLinkAction.static.methods =
ve.ui.MWLinkAction.super.static.methods.concat( [ 'open' ] );
+ve.ui.MWLinkAction.static.methods =
ve.ui.MWLinkAction.super.static.methods.concat( [ 'open', 'autolinkMagicLink' ]
);
/* Methods */
@@ -53,14 +53,27 @@
* @inheritdoc
* @return {ve.dm.MWExternalLinkAnnotation} The annotation to use.
*/
-ve.ui.MWLinkAction.prototype.getLinkAnnotation = function ( href ) {
- var title,
+ve.ui.MWLinkAction.prototype.getLinkAnnotation = function ( linktext ) {
+ var title, targetData, m,
+ href = linktext;
+ // The link has been validated in #autolinkMagicLink and/or
+ // #autolinkUrl, so we can use a quick and dirty regexp here to pull
+ // apart the magic link.
+ m = /^(RFC|PMID|ISBN)\s+(\S.*)$/.exec( linktext );
+ if ( m && m[ 1 ] === 'RFC' ) {
+ href = '//tools.ietf.org/html/rfc' + m[ 2 ];
+ } else if ( m && m[ 1 ] === 'PMID' ) {
+ href = '//www.ncbi.nlm.nih.gov/pubmed/' + m[ 2 ] +
'?dopt=Abstract';
+ } else if ( m && m[ 1 ] === 'ISBN' ) {
+ title = mw.Title.newFromText( 'Special:BookSources/' + m[ 2
].replace( /[^0-9Xx]/g, '' ) );
+ } else {
targetData =
ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref(
href,
this.surface.getModel().getDocument().getHtmlDocument()
);
- if ( targetData.isInternal ) {
- title = mw.Title.newFromText( targetData.title );
+ if ( targetData.isInternal ) {
+ title = mw.Title.newFromText( targetData.title );
+ }
}
return title ?
ve.dm.MWInternalLinkAnnotation.static.newFromTitle( title ) :
@@ -68,6 +81,27 @@
type: 'link/mwExternal',
attributes: { href: href }
} );
+};
+
+/**
+ * Autolink the selected RFC/PMID/ISBN, which may have trailing whitespace.
+ *
+ * @see ve.ui.LinkAction#autolinkUrl
+ * @method
+ * @return {boolean}
+ * True if the selection is a valid RFC/PMID/ISBN and the autolink action
+ * was executed; otherwise false.
+ */
+ve.ui.MWLinkAction.prototype.autolinkMagicLink = function () {
+ return this.autolink( function ( linktext ) {
+ if ( /^(RFC|PMID) [0-9]+$/.test( linktext ) ) {
+ return true; // Valid RFC/PMID
+ }
+ if ( /^ISBN (97[89][- ]?)?([0-9][- ]?){9}[0-9Xx]$/.test(
linktext ) ) {
+ return true; // Valid ISBN
+ }
+ return false;
+ } );
};
/**
@@ -90,3 +124,16 @@
/* Registration */
ve.ui.actionFactory.register( ve.ui.MWLinkAction );
+
+ve.ui.commandRegistry.register(
+ new ve.ui.Command(
+ 'autolinkMagicLink', ve.ui.MWLinkAction.static.name,
'autolinkMagicLink',
+ { supportedSelections: [ 'linear' ] }
+ )
+);
+
+ve.ui.sequenceRegistry.register(
+ // This regexp doesn't have to be precise; we'll validate the magic
+ // link in #autolinkMagicLink above.
+ new ve.ui.Sequence( 'autolinkMagicLink', 'autolinkMagicLink',
/\b(RFC|PMID|ISBN)\s+[0-9]([- 0-9]*[0-9Xx])?(\s|\n\n)$/, 0, true )
+);
--
To view, visit https://gerrit.wikimedia.org/r/232391
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5650410d7fca30c90baddd4f0c3f6d80e6b39042
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Cscott <[email protected]>
Gerrit-Reviewer: Cscott <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits