mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-11 05:56:11 +00:00
eb515188ec
`new mw.Title` throws on invalid input. Converting uses to mw.Title.newFromText instead and converting try/catch to if/else. mw.Title in general (regardless of which constructor) has been improved in core. It will no longer crash on pages where the page title was a false hit for invalid (e.g. we couldn't load VE on [[.com]] because the js parser thought it was invalid). However, though the initialisation works since core has been fixed, there are still plently of cases where we take real user input that can genuinely be invalid. In cases where the code did not catch exceptions and there was no obvious way to handle it, I left it as is (let's revisit them in a separate commit). It would be an exception either way, and I'd rather see "mw.Title: Parser error" than "TypeError: null does not have method getNamespaceId". Change-Id: I5b1b23d56d39cdb7ecb0809e3d721992e0c30f54
109 lines
3.1 KiB
JavaScript
109 lines
3.1 KiB
JavaScript
/*!
|
|
* VisualEditor DataModel MWInternalLinkAnnotation class.
|
|
*
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/*global mw */
|
|
|
|
/**
|
|
* 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( element ) {
|
|
// Parent constructor
|
|
ve.dm.LinkAnnotation.call( this, element );
|
|
};
|
|
|
|
/* Inheritance */
|
|
|
|
ve.inheritClass( ve.dm.MWInternalLinkAnnotation, ve.dm.LinkAnnotation );
|
|
|
|
/* Static Properties */
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.name = 'link/mwInternal';
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.matchRdfaTypes = ['mw:WikiLink'];
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.toDataElement = function ( domElements ) {
|
|
// Get title from href
|
|
// 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
|
|
/*jshint regexp:false */
|
|
var matches = domElements[0].getAttribute( 'href' ).match( /^((?:\.\.?\/)*)(.*)$/ ),
|
|
// Normalize capitalisation and underscores
|
|
normalizedTitle = ve.dm.MWInternalLinkAnnotation.static.normalizeTitle( matches[2] );
|
|
return {
|
|
'type': 'link/mwInternal',
|
|
'attributes': {
|
|
'hrefPrefix': matches[1],
|
|
'title': decodeURIComponent( matches[2] ).replace( /_/g, ' ' ),
|
|
'normalizedTitle': normalizedTitle,
|
|
'origTitle': matches[2]
|
|
}
|
|
};
|
|
};
|
|
|
|
ve.dm.MWInternalLinkAnnotation.static.toDomElements = function ( dataElement, doc ) {
|
|
var href,
|
|
domElement = doc.createElement( 'a' ),
|
|
title = dataElement.attributes.title,
|
|
origTitle = dataElement.attributes.origTitle;
|
|
if ( origTitle && decodeURIComponent( origTitle ).replace( /_/g, ' ' ) === title ) {
|
|
// Restore href from origTitle
|
|
href = origTitle;
|
|
// Only use hrefPrefix if restoring from origTitle
|
|
if ( dataElement.attributes.hrefPrefix ) {
|
|
href = dataElement.attributes.hrefPrefix + href;
|
|
}
|
|
} else {
|
|
href = encodeURIComponent( title );
|
|
}
|
|
domElement.setAttribute( 'href', href );
|
|
domElement.setAttribute( 'rel', 'mw:WikiLink' );
|
|
return [ domElement ];
|
|
};
|
|
|
|
/**
|
|
* Normalize title for comparison purposes
|
|
* @param {string} title Original title
|
|
* @returns {string} Normalized title, or the original if it is invalid
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.static.normalizeTitle = function ( original ) {
|
|
var title = mw.Title.newFromText( original );
|
|
return title ? title.getPrefixedText() : original;
|
|
};
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* @returns {Object}
|
|
*/
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getComparableObject = function () {
|
|
return {
|
|
'type': this.getType(),
|
|
'normalizedTitle': this.getAttribute( 'normalizedTitle' )
|
|
};
|
|
};
|
|
|
|
/** */
|
|
ve.dm.MWInternalLinkAnnotation.prototype.getComparableHtmlAttributes = function () {
|
|
var attributes = ve.dm.Annotation.prototype.getComparableHtmlAttributes.call( this );
|
|
delete attributes.href;
|
|
delete attributes.rel;
|
|
return attributes;
|
|
};
|
|
|
|
/* Registration */
|
|
|
|
ve.dm.modelRegistry.register( ve.dm.MWInternalLinkAnnotation );
|