mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-23 22:13:34 +00:00
Builder for ve.dm.MWInternalLinkAnnotation
Add ve.dm.MWInternalLinkAnnotation.static.newFromTitle to build an appropriate internal link annotation from a mw.Title. Tweaked some method signatures to avoid repeated reparsing of the title text. Also refactor ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref to explicitly return a boolean indicating whether the result was determined to be an internal link. Bug: T64816 Change-Id: I74385d7b3ede1794398dabb749185f4080509b99
This commit is contained in:
parent
bf520fee03
commit
2852f6368f
|
@ -50,15 +50,47 @@ ve.dm.MWInternalLinkAnnotation.static.toDataElement = function ( domElements, co
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a ve.dm.MWInternalLinkAnnotation from a given mw.Title.
|
||||
*
|
||||
* @param {mw.Title} title The title to link to.
|
||||
* @return {ve.dm.MWInternalLinkAnnotation} The annotation.
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.static.newFromTitle = function ( title ) {
|
||||
var target = title.toText();
|
||||
|
||||
if ( title.getNamespaceId() === 6 || title.getNamespaceId() === 14 ) {
|
||||
// File: or Category: link
|
||||
// We have to prepend a colon so this is interpreted as a link
|
||||
// rather than an image inclusion or categorization
|
||||
target = ':' + target;
|
||||
}
|
||||
|
||||
return new ve.dm.MWInternalLinkAnnotation( {
|
||||
type: 'link/mwInternal',
|
||||
attributes: {
|
||||
title: target,
|
||||
normalizedTitle: ve.dm.MWInternalLinkAnnotation.static.normalizeTitle( title ),
|
||||
lookupTitle: ve.dm.MWInternalLinkAnnotation.static.getLookupTitle( title )
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse URL to get title it points to.
|
||||
*
|
||||
* @param {string} href
|
||||
* @param {HTMLDocument|string} doc Document whose base URL to use, or base URL as a string.
|
||||
* @return {Object} Plain object with 'title' and 'hrefPrefix' keys.
|
||||
* @return {Object} Information about the given href
|
||||
* @return {string} return.title
|
||||
* The title of the internal link, else the original href if href is external
|
||||
* @return {string} return.hrefPrefix
|
||||
* Any ./ or ../ prefixes on a relative link
|
||||
* @return {boolean} return.isInternal
|
||||
* True if the href pointed to the local wiki, false if href is external
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref = function ( href, doc ) {
|
||||
var relativeBase, relativeBaseRegex, relativeHref, matches;
|
||||
var relativeBase, relativeBaseRegex, relativeHref, isInternal, matches;
|
||||
|
||||
function regexEscape( str ) {
|
||||
return str.replace( /([.?*+^$[\]\\(){}|-])/g, '\\$1' );
|
||||
|
@ -69,19 +101,22 @@ ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref = function ( href, d
|
|||
relativeBaseRegex = new RegExp( regexEscape( relativeBase ).replace( regexEscape( '$1' ), '(.*)' ) );
|
||||
// Protocol relative href
|
||||
relativeHref = href.replace( /^https?:/, '' );
|
||||
// Paths without a host portion are assumed to be internal
|
||||
isInternal = !/^\/\//.test( relativeHref );
|
||||
// Check if this matches the server's article path
|
||||
matches = relativeHref.match( relativeBaseRegex );
|
||||
|
||||
if ( matches ) {
|
||||
// Take the relative path
|
||||
href = matches[ 1 ];
|
||||
isInternal = true;
|
||||
}
|
||||
|
||||
// The href is simply the title, unless we're dealing with a page that has slashes in its name
|
||||
// in which case it's preceded by one or more instances of "./" or "../", so strip those
|
||||
matches = href.match( /^((?:\.\.?\/)*)(.*)$/ );
|
||||
|
||||
return { title: matches[ 2 ], hrefPrefix: matches[ 1 ] };
|
||||
return { title: matches[ 2 ], hrefPrefix: matches[ 1 ], isInternal: isInternal };
|
||||
};
|
||||
|
||||
ve.dm.MWInternalLinkAnnotation.static.toDomElements = function () {
|
||||
|
@ -111,11 +146,11 @@ ve.dm.MWInternalLinkAnnotation.static.getHref = function ( dataElement ) {
|
|||
* Normalize title for comparison purposes.
|
||||
* E.g. capitalisation and underscores.
|
||||
*
|
||||
* @param {string} original Original title
|
||||
* @return {string} Normalized title, or the original if it is invalid
|
||||
* @param {string|mw.Title} original Original title
|
||||
* @return {string} Normalized title, or the original string if it is invalid
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.static.normalizeTitle = function ( original ) {
|
||||
var title = mw.Title.newFromText( original );
|
||||
var title = original instanceof mw.Title ? original : mw.Title.newFromText( original );
|
||||
if ( !title ) {
|
||||
return original;
|
||||
}
|
||||
|
@ -125,11 +160,11 @@ ve.dm.MWInternalLinkAnnotation.static.normalizeTitle = function ( original ) {
|
|||
/**
|
||||
* Normalize title for lookup (search suggestion, existence) purposes.
|
||||
*
|
||||
* @param {string} original Original title
|
||||
* @return {string} Normalized title, or the original if it is invalid
|
||||
* @param {string|mw.Title} original Original title
|
||||
* @return {string} Normalized title, or the original string if it is invalid
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.static.getLookupTitle = function ( original ) {
|
||||
var title = mw.Title.newFromText( original );
|
||||
var title = original instanceof mw.Title ? original : mw.Title.newFromText( original );
|
||||
if ( !title ) {
|
||||
return original;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ ve.ui.MWLinkAnnotationInspector.prototype.isExternal = function () {
|
|||
* @param {ve.dm.MWInternalLinkAnnotation} annotation Annotation
|
||||
*/
|
||||
ve.ui.MWLinkAnnotationInspector.prototype.onInternalLinkChange = function ( annotation ) {
|
||||
var title,
|
||||
var targetData,
|
||||
href = annotation ? annotation.getAttribute( 'title' ) : '',
|
||||
// Have to check that this.getFragment() is defined because parent class's teardown
|
||||
// invokes setAnnotation( null ) which calls this code after fragment is unset
|
||||
|
@ -101,12 +101,12 @@ ve.ui.MWLinkAnnotationInspector.prototype.onInternalLinkChange = function ( anno
|
|||
if ( htmlDoc && ve.init.platform.getExternalLinkUrlProtocolsRegExp().test( href ) ) {
|
||||
// Check if the 'external' link is in fact a page on the same wiki
|
||||
// e.g. http://en.wikipedia.org/wiki/Target -> Target
|
||||
title = ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref(
|
||||
targetData = ve.dm.MWInternalLinkAnnotation.static.getTargetDataFromHref(
|
||||
href,
|
||||
htmlDoc
|
||||
).title;
|
||||
if ( title !== href ) {
|
||||
this.internalAnnotationInput.text.setValue( title );
|
||||
);
|
||||
if ( targetData.isInternal ) {
|
||||
this.internalAnnotationInput.text.setValue( targetData.title );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -226,23 +226,7 @@ ve.ui.MWLinkAnnotationInspector.prototype.getAnnotationFromFragment = function (
|
|||
} );
|
||||
} else if ( title ) {
|
||||
// Internal link
|
||||
|
||||
if ( title.getNamespaceId() === 6 || title.getNamespaceId() === 14 ) {
|
||||
// File: or Category: link
|
||||
// We have to prepend a colon so this is interpreted as a link
|
||||
// rather than an image inclusion or categorization
|
||||
target = ':' + target;
|
||||
}
|
||||
|
||||
return new ve.dm.MWInternalLinkAnnotation( {
|
||||
type: 'link/mwInternal',
|
||||
attributes: {
|
||||
title: target,
|
||||
// bug 62816: we really need a builder for this stuff
|
||||
normalizedTitle: ve.dm.MWInternalLinkAnnotation.static.normalizeTitle( target ),
|
||||
lookupTitle: ve.dm.MWInternalLinkAnnotation.static.getLookupTitle( target )
|
||||
}
|
||||
} );
|
||||
return ve.dm.MWInternalLinkAnnotation.static.newFromTitle( title );
|
||||
} else {
|
||||
// Doesn't look like an external link and mw.Title considered it an illegal value,
|
||||
// for an internal link.
|
||||
|
|
Loading…
Reference in a new issue