2015-05-03 21:21:00 +00:00
|
|
|
/*!
|
|
|
|
* VisualEditor UserInterface MWInternalLinkAnnotationWidget class.
|
|
|
|
*
|
2020-01-08 17:13:04 +00:00
|
|
|
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
|
2015-05-03 21:21:00 +00:00
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an ve.ui.MWInternalLinkAnnotationWidget object.
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @extends ve.ui.LinkAnnotationWidget
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @param {Object} [config] Configuration options
|
|
|
|
*/
|
|
|
|
ve.ui.MWInternalLinkAnnotationWidget = function VeUiMWInternalLinkAnnotationWidget() {
|
|
|
|
// Parent constructor
|
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.super.apply( this, arguments );
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
|
|
|
OO.inheritClass( ve.ui.MWInternalLinkAnnotationWidget, ve.ui.LinkAnnotationWidget );
|
|
|
|
|
2015-05-29 12:08:05 +00:00
|
|
|
/* Static Methods */
|
2015-05-03 21:21:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2015-05-29 12:08:05 +00:00
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.static.getAnnotationFromText = function ( value ) {
|
2017-03-23 12:54:37 +00:00
|
|
|
var trimmed = value.trim(),
|
|
|
|
title = mw.Title.newFromText( trimmed );
|
2015-05-03 21:21:00 +00:00
|
|
|
|
2015-08-25 15:39:32 +00:00
|
|
|
if ( !title ) {
|
2015-05-03 21:21:00 +00:00
|
|
|
return null;
|
|
|
|
}
|
2017-03-23 12:54:37 +00:00
|
|
|
return ve.dm.MWInternalLinkAnnotation.static.newFromTitle( title, trimmed );
|
2015-05-03 21:21:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
2015-05-29 12:08:05 +00:00
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.static.getTextFromAnnotation = function ( annotation ) {
|
2019-06-26 15:16:17 +00:00
|
|
|
return annotation ? annotation.getAttribute( 'normalizedTitle' ) : '';
|
2015-05-03 21:21:00 +00:00
|
|
|
};
|
2015-05-29 12:08:05 +00:00
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a text input widget to be used by the annotation widget
|
|
|
|
*
|
|
|
|
* @param {Object} [config] Configuration options
|
|
|
|
* @return {OO.ui.TextInputWidget} Text input widget
|
|
|
|
*/
|
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.prototype.createInputWidget = function ( config ) {
|
2016-03-08 10:26:31 +00:00
|
|
|
var input = new mw.widgets.TitleSearchWidget( ve.extendObject( {
|
2015-05-29 12:08:05 +00:00
|
|
|
icon: 'search',
|
2016-09-30 19:40:07 +00:00
|
|
|
excludeCurrentPage: true,
|
2019-04-16 23:09:23 +00:00
|
|
|
showImages: mw.config.get( 'wgVisualEditorConfig' ).usePageImages,
|
|
|
|
showDescriptions: mw.config.get( 'wgVisualEditorConfig' ).usePageDescriptions,
|
2019-05-08 18:48:24 +00:00
|
|
|
showInterwikis: true,
|
2019-08-27 11:17:44 +00:00
|
|
|
addQueryInput: false,
|
2018-05-04 13:30:10 +00:00
|
|
|
api: ve.init.target.getContentApi(),
|
2015-06-15 10:25:44 +00:00
|
|
|
cache: ve.init.platform.linkCache
|
2015-09-25 20:29:10 +00:00
|
|
|
}, config ) );
|
2016-03-08 10:26:31 +00:00
|
|
|
|
|
|
|
// Put query first in DOM
|
|
|
|
// TODO: Consider upstreaming this to SearchWidget
|
|
|
|
input.$element.prepend( input.$query );
|
|
|
|
|
2019-07-29 20:03:31 +00:00
|
|
|
// Remove 'maxlength', because it should not apply to full URLs, which we allow users to paste
|
|
|
|
// here. Maximum length of page titles will still be enforced by JS validation later (we can't
|
|
|
|
// override maxLength config option, because that would break the validation).
|
|
|
|
input.getQuery().$input.removeAttr( 'maxlength' );
|
|
|
|
|
2020-02-14 19:11:39 +00:00
|
|
|
input.query.$input.attr( 'aria-label', mw.msg( 'visualeditor-linkinspector-button-link-internal' ) );
|
2016-03-08 10:26:31 +00:00
|
|
|
return input;
|
2015-09-25 20:29:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.prototype.getTextInputWidget = function () {
|
|
|
|
return this.input.query;
|
2015-05-29 12:08:05 +00:00
|
|
|
};
|
2015-06-23 21:06:10 +00:00
|
|
|
|
2018-05-05 13:31:20 +00:00
|
|
|
// #getHref returns the link title, not a fully resolved URL, however the only
|
|
|
|
// use case of widget.getHref is for link insertion text, which expects a title.
|
|
|
|
//
|
|
|
|
// Callers needing the full resolved URL should use ve.resolveUrl
|
2016-07-15 18:35:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
|
|
|
ve.ui.MWInternalLinkAnnotationWidget.prototype.onTextChange = function ( value ) {
|
|
|
|
var targetData,
|
2019-05-02 16:59:05 +00:00
|
|
|
htmlDoc = this.getElementDocument(),
|
|
|
|
namespacesWithSubpages = mw.config.get( 'wgVisualEditorConfig' ).namespacesWithSubpages,
|
|
|
|
basePageObj = mw.Title.newFromText( mw.config.get( 'wgRelevantPageName' ) );
|
2016-07-15 18:35:56 +00:00
|
|
|
// Specific thing we want to check: has a valid URL for an internal page
|
|
|
|
// been pasted into here, in which case we want to convert it to just the
|
|
|
|
// page title. This has to happen /here/ because a URL can reference a
|
|
|
|
// valid page while not being a valid Title (e.g. if it contains a "%").
|
|
|
|
if ( ve.init.platform.getExternalLinkUrlProtocolsRegExp().test( value ) ) {
|
2020-03-20 17:08:24 +00:00
|
|
|
targetData = mw.libs.ve.getTargetDataFromHref(
|
2016-07-15 18:35:56 +00:00
|
|
|
value,
|
|
|
|
htmlDoc
|
|
|
|
);
|
|
|
|
if ( targetData.isInternal ) {
|
|
|
|
value = targetData.title;
|
|
|
|
this.input.query.setValue( targetData.title );
|
|
|
|
}
|
2019-05-02 16:59:05 +00:00
|
|
|
} else if ( namespacesWithSubpages[ basePageObj.namespace ] && value[ 0 ] === '/' ) {
|
|
|
|
// This does make it more-difficult to deliberately link to a page in the
|
|
|
|
// default namespace that starts with a / when you're on a subpage-allowing
|
|
|
|
// namespace. However, the exact same trick you need to know to make it work
|
|
|
|
// in plain wikitext applies: search for `:/foo`.
|
|
|
|
value = basePageObj.getPrefixedText() + value;
|
|
|
|
this.input.query.setValue( value );
|
2016-07-15 18:35:56 +00:00
|
|
|
}
|
|
|
|
return ve.ui.MWInternalLinkAnnotationWidget.super.prototype.onTextChange.call( this, value );
|
|
|
|
};
|