/*!
* VisualEditor UserInterface LinkAnnotationWidget class.
*
* @copyright See AUTHORS.txt
*/
/**
* Creates an ve.ui.LinkAnnotationWidget object.
*
* @class
* @extends OO.ui.Widget
*
* @constructor
* @param {Object} [config] Configuration options
*/
ve.ui.LinkAnnotationWidget = function VeUiLinkAnnotationWidget( config ) {
// Properties
this.annotation = null;
this.input = this.createInputWidget( config );
// Parent constructor
// Must be called after this.input is set as parent constructor calls this.setDisabled
ve.ui.LinkAnnotationWidget.super.apply( this, arguments );
// Initialization
this.$element
.append( this.input.$element )
.addClass( 've-ui-linkAnnotationWidget' );
// Events
this.getTextInputWidget().connect( this, { change: 'onTextChange' } );
};
/* Inheritance */
OO.inheritClass( ve.ui.LinkAnnotationWidget, OO.ui.Widget );
/* Events */
/**
* A change event is emitted when the annotation value of the input changes.
*
* @event ve.ui.LinkAnnotationWidget#change
* @param {ve.dm.LinkAnnotation|null} annotation
*/
/* Static Methods */
/**
* Get an annotation from the current text value
*
* @static
* @param {string} value Text value
* @return {ve.dm.LinkAnnotation|null} Link annotation
*/
ve.ui.LinkAnnotationWidget.static.getAnnotationFromText = function ( value ) {
const href = value.trim();
// Keep annotation in sync with value
if ( href === '' ) {
return null;
} else {
return new ve.dm.LinkAnnotation( {
type: 'link',
attributes: {
href: href
}
} );
}
};
/**
* Get a text value for the current annotation
*
* @static
* @param {ve.dm.LinkAnnotation|null} annotation Link annotation
* @return {string} Text value for the annotation
*/
ve.ui.LinkAnnotationWidget.static.getTextFromAnnotation = function ( annotation ) {
return annotation ? annotation.getHref() : '';
};
/* Methods */
/**
* Create a widget to be used by the annotation widget
*
* @param {Object} [config] Configuration options
* @return {OO.ui.Widget} Text input widget
*/
ve.ui.LinkAnnotationWidget.prototype.createInputWidget = function ( config ) {
return new OO.ui.TextInputWidget( ve.extendObject( { validate: 'non-empty' }, config ) );
};
/**
* Get the text input widget used by the annotation widget
*
* @return {OO.ui.TextInputWidget} Text input widget
*/
ve.ui.LinkAnnotationWidget.prototype.getTextInputWidget = function () {
return this.input;
};
/**
* @inheritdoc
*/
ve.ui.LinkAnnotationWidget.prototype.setDisabled = function () {
// Parent method
ve.ui.LinkAnnotationWidget.super.prototype.setDisabled.apply( this, arguments );
this.getTextInputWidget().setDisabled( this.isDisabled() );
return this;
};
/**
* Handle value-changing events from the text input
*
* @param {string} value New input value
*/
ve.ui.LinkAnnotationWidget.prototype.onTextChange = function ( value ) {
// RTL/LTR check
// TODO: Make this work properly
if ( document.body.classList.contains( 'rtl' ) ) {
const isExt = ve.init.platform.getExternalLinkUrlProtocolsRegExp().test( value.trim() );
// If URL is external, flip to LTR. Otherwise, set back to RTL
this.getTextInputWidget().setDir( isExt ? 'ltr' : 'rtl' );
}
this.getTextInputWidget().getValidity()
.done( () => {
this.setAnnotation( this.constructor.static.getAnnotationFromText( value ), true );
} )
.fail( () => {
this.setAnnotation( null, true );
} );
};
/**
* Sets the annotation value.
*
* The input value will automatically be updated.
*
* @param {ve.dm.LinkAnnotation|null} annotation Link annotation
* @param {boolean} [fromText] Annotation was generated from text input
* @return {ve.ui.LinkAnnotationWidget}
* @chainable
* @fires ve.ui.LinkAnnotationWidget#change
*/
ve.ui.LinkAnnotationWidget.prototype.setAnnotation = function ( annotation, fromText ) {
if ( ve.compare(
annotation ? annotation.getComparableObject() : {},
this.annotation ? this.annotation.getComparableObject() : {}
) ) {
// No change
return this;
}
this.annotation = annotation;
// If this method was triggered by a change to the text input, leave it alone.
if ( !fromText ) {
this.getTextInputWidget().setValue( this.constructor.static.getTextFromAnnotation( annotation ) );
}
this.emit( 'change', this.annotation );
return this;
};
/**
* Gets the annotation value.
*
* @return {ve.dm.LinkAnnotation} Link annotation
*/
ve.ui.LinkAnnotationWidget.prototype.getAnnotation = function () {
return this.annotation;
};
/**
* Get the hyperlink location.
*
* @return {string} Hyperlink location
*/
ve.ui.LinkAnnotationWidget.prototype.getHref = function () {
return this.constructor.static.getTextFromAnnotation( this.annotation );
};
/**
* Set the read-only state of the widget
*
* @param {boolean} readOnly Make widget read-only
* @return {ve.ui.LinkAnnotationWidget}
* @chainable
*/
ve.ui.LinkAnnotationWidget.prototype.setReadOnly = function ( readOnly ) {
this.input.setReadOnly( readOnly );
return this;
};