mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-27 13:33:00 +00:00
25019d7f55
Our encoding for the hrefs like "./Foo" that we send to Parsoid differed slightly from how Parsoid outputs them, so to avoid dirty diffs, we had to store the original ones we received from Parsoid and send them back if they were unchanged. Change the encoding to match Parsoid's exactly (by referring to the Parsoid source code), and then remove 'rawTitle'/'origTitle'. On a historical note, 'rawTitle'/'origTitle' were originally added to fix other issues with links, which I hope are long behind us: *bb45d984ca
(T145978) *fda2e6c1b5
(T44140) Follow-up to362df66b47
, which removed some other old stuff from the handling of Parsoid links. Bug: T325766 Change-Id: I0ad0a655380eb2fb29b5ac01e2e399ac550ce34a
214 lines
6 KiB
JavaScript
214 lines
6 KiB
JavaScript
/*!
|
|
* VisualEditor DataModel MWInternalLinkAnnotation class.
|
|
*
|
|
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* DataModel MediaWiki internal link annotation.
|
|
*
|
|
* Example HTML sources:
|
|
*
|
|
* <a rel="mw:WikiLink">
|
|
*
|
|
* @class
|
|
* @extends ve.dm.LinkAnnotation
|
|
* @constructor
|
|
* @param {Object} element
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation = function VeDmMWInternalLinkAnnotation() {
|
|
// Parent constructor
|
|
ve.dm.MWInternalLinkAnnotation.super.apply( this, arguments );
|
|
};
|
|
|
|
/* Inheritance */
|
|
|
|
OO.inheritClass( ve.dm.MWInternalLinkAnnotation, ve.dm.LinkAnnotation );
|
|
|
|
/* Static Properties */
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.name = 'link/mwInternal';
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.matchRdfaTypes = [ 'mw:WikiLink', 'mw:MediaLink' ];
|
|
|
|
// mw:MediaLink to non-existent files come with typeof="mw:Error"
|
|
ve.dm.MWInternalLinkAnnotation.static.allowedRdfaTypes = [ 'mw:Error', 'mw:LocalizedAttrs' ];
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.toDataElement = function ( domElements, converter ) {
|
|
var resource = domElements[ 0 ].getAttribute( 'resource' );
|
|
|
|
var targetData;
|
|
if ( resource ) {
|
|
targetData = mw.libs.ve.parseParsoidResourceName( resource );
|
|
} else {
|
|
targetData = mw.libs.ve.getTargetDataFromHref(
|
|
domElements[ 0 ].getAttribute( 'href' ),
|
|
converter.getTargetHtmlDocument()
|
|
);
|
|
|
|
if ( !targetData.isInternal ) {
|
|
return ve.dm.MWExternalLinkAnnotation.static.toDataElement( domElements, converter );
|
|
}
|
|
}
|
|
|
|
return {
|
|
type: this.name,
|
|
attributes: {
|
|
title: targetData.title,
|
|
normalizedTitle: this.normalizeTitle( targetData.title ),
|
|
lookupTitle: this.getLookupTitle( targetData.title )
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Build element from a given mw.Title and raw title
|
|
*
|
|
* @param {mw.Title} title The title to link to.
|
|
* @return {Object} The element.
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.static.dataElementFromTitle = function ( title ) {
|
|
var target = title.toText();
|
|
|
|
if ( title.getFragment() ) {
|
|
target += '#' + title.getFragment();
|
|
}
|
|
|
|
var element = {
|
|
type: this.name,
|
|
attributes: {
|
|
title: target,
|
|
normalizedTitle: this.normalizeTitle( title ),
|
|
lookupTitle: this.getLookupTitle( title )
|
|
}
|
|
};
|
|
|
|
return element;
|
|
};
|
|
|
|
/**
|
|
* 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 element = this.dataElementFromTitle( title );
|
|
|
|
return new ve.dm.MWInternalLinkAnnotation( element );
|
|
};
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.toDomElements = function () {
|
|
var parentResult = ve.dm.LinkAnnotation.static.toDomElements.apply( this, arguments );
|
|
// we just created that link so the 'rel' attribute should be safe
|
|
parentResult[ 0 ].setAttribute( 'rel', 'mw:WikiLink' );
|
|
return parentResult;
|
|
};
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.getHref = function ( dataElement ) {
|
|
var title = dataElement.attributes.title;
|
|
|
|
if ( title.slice( 0, 1 ) === '#' ) {
|
|
// Special case: For a newly created link to a #fragment with
|
|
// no explicit title use the current title as prefix (T218581)
|
|
// TODO: Pass a 'doc' param to getPageName
|
|
title = ve.init.target.getPageName() + title;
|
|
}
|
|
|
|
return mw.libs.ve.encodeParsoidResourceName( title );
|
|
};
|
|
|
|
/**
|
|
* Normalize title for comparison purposes.
|
|
* E.g. capitalisation and underscores.
|
|
*
|
|
* @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 = original instanceof mw.Title ? original : mw.Title.newFromText( original );
|
|
if ( !title ) {
|
|
return original;
|
|
}
|
|
return title.getPrefixedText() + ( title.getFragment() !== null ? '#' + title.getFragment() : '' );
|
|
};
|
|
|
|
/**
|
|
* Normalize title for lookup (search suggestion, existence) purposes.
|
|
*
|
|
* @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 = original instanceof mw.Title ? original : mw.Title.newFromText( original );
|
|
if ( !title ) {
|
|
return original;
|
|
}
|
|
return title.getPrefixedText();
|
|
};
|
|
|
|
/**
|
|
* Get the fragment for a title
|
|
*
|
|
* @static
|
|
* @param {string|mw.Title} original Original title
|
|
* @return {string|null} Fragment for the title, or null if it was invalid or missing
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.static.getFragment = function ( original ) {
|
|
var title = original instanceof mw.Title ? original : mw.Title.newFromText( original );
|
|
if ( !title ) {
|
|
return null;
|
|
}
|
|
return title.getFragment();
|
|
};
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.describeChange = function ( key, change ) {
|
|
if ( key === 'title' ) {
|
|
return ve.htmlMsg( 'visualeditor-changedesc-link-href', this.wrapText( 'del', change.from ), this.wrapText( 'ins', change.to ) );
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getComparableObject = function () {
|
|
return {
|
|
type: this.getType(),
|
|
normalizedTitle: this.getAttribute( 'normalizedTitle' )
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getComparableHtmlAttributes = function () {
|
|
// Assume that wikitext never adds meaningful html attributes for comparison purposes,
|
|
// although ideally this should be decided by Parsoid (Bug T95028).
|
|
return {};
|
|
};
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getDisplayTitle = function () {
|
|
return this.getAttribute( 'normalizedTitle' );
|
|
};
|
|
|
|
/**
|
|
* Convenience wrapper for .getFragment() on the current element.
|
|
*
|
|
* @see #static-getFragment
|
|
* @return {string} Fragment for the title, or an empty string if it was invalid
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getFragment = function () {
|
|
return this.constructor.static.getFragment( this.getAttribute( 'normalizedTitle' ) );
|
|
};
|
|
|
|
/* Registration */
|
|
|
|
ve.dm.modelRegistry.register( ve.dm.MWInternalLinkAnnotation );
|