',
init: function () {
function isExternalLink( s ) {
// The following things are considered to be external links:
// * Starts a URL protocol
// * Starts with www.
// All of these are potentially valid titles, and the latter two categories match about 6300
// titles in enwiki's ns0. Out of 6.9M titles, that's 0.09%
if ( typeof arguments.callee.regex === 'undefined' ) {
// Cache the regex
arguments.callee.regex =
new RegExp( "^(" + mw.config.get( 'wgUrlProtocols' ) + "|www\\.)", 'i');
}
return s.match( arguments.callee.regex );
}
// Updates the status indicator above the target link
function updateWidget( status ) {
$( '#wikieditor-toolbar-link-int-target-status' ).children().hide();
$( '#wikieditor-toolbar-link-int-target' ).parent()
.removeClass(
'status-invalid status-external status-notexists status-exists status-loading'
);
if ( status ) {
$( '#wikieditor-toolbar-link-int-target-status-' + status ).show();
$( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status );
}
if ( status === 'invalid' ) {
$( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
.attr( 'disabled', true )
.addClass( 'disabled' );
} else {
$( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
.removeAttr('disabled')
.removeClass('disabled');
}
}
// Updates the UI to show if the page title being inputed by the user exists or not
// accepts parameter internal for bypassing external link detection
function updateExistence( internal ) {
// ensure the internal parameter is a boolean
if ( internal !== true ) {
internal = false;
}
// Abort previous request
var request = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
if ( request ) {
request.abort();
}
var target = $( '#wikieditor-toolbar-link-int-target' ).val();
var cache = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'existencecache' );
if ( cache[target] ) {
updateWidget( cache[target] );
return;
}
if ( target.replace( /^\s+$/,'' ) === '' ) {
// Hide the widget when the textbox is empty
updateWidget( false );
return;
}
// If the forced internal paremter was not true, check if the target is an external link
if ( !internal && isExternalLink( target ) ) {
updateWidget( 'external' );
return;
}
if ( target.indexOf( '|' ) !== -1 ) {
// Title contains | , which means it's invalid
// but confuses the API. Show invalid and bypass API
updateWidget( 'invalid' );
return;
}
// Show loading spinner while waiting for the API to respond
updateWidget( 'loading' );
// Call the API to check page status, saving the request object so it can be aborted if
// necessary.
// This used to request a page that would show whether or not the target exists, but we can
// also check whether it has the disambiguation property and still get existence information.
// If the Disambiguator extension is not installed then such a property won't be set.
$( '#wikieditor-toolbar-link-int-target-status' ).data(
'request',
( new mw.Api() ).get( {
action: 'query',
prop: 'pageprops',
titles: target,
ppprop: 'disambiguation',
indexpageids: true
} ).done( function ( data ) {
var status;
if ( !data.query ) {
// This happens in some weird cases
status = false;
} else {
var page = data.query.pages[data.query.pageids[0]];
status = 'exists';
if ( page.missing !== undefined ) {
status = 'notexists';
} else if ( page.invalid !== undefined ) {
status = 'invalid';
} else if ( page.pageprops !== undefined ) {
status = 'disambig';
}
}
// Cache the status of the link target if the force internal
// parameter was not passed
if ( !internal ) {
cache[target] = status;
}
updateWidget( status );
} )
);
}
$( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).click( function () {
if ( $( '#wikieditor-toolbar-link-type-ext' ).prop( 'checked' ) ) {
// Abort previous request
var request = $( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
if ( request ) {
request.abort();
}
updateWidget( 'external' );
}
if ( $( '#wikieditor-toolbar-link-type-int' ).prop( 'checked' ) ) {
updateExistence( true );
}
});
// Set labels of tabs based on rel values
$(this).find( '[rel]' ).each( function () {
$(this).text( mw.msg( $(this).attr( 'rel' ) ) );
});
// Set tabindexes on form fields
$.wikiEditor.modules.dialogs.fn.setTabindexes( $(this).find( 'input' ).not( '[tabindex]' ) );
// Setup the tooltips in the textboxes
$( '#wikieditor-toolbar-link-int-target' )
.data( 'tooltip', mw.msg( 'wikieditor-toolbar-tool-link-int-target-tooltip' ) );
$( '#wikieditor-toolbar-link-int-text' )
.data( 'tooltip', mw.msg( 'wikieditor-toolbar-tool-link-int-text-tooltip' ) );
$( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' )
.each( function () {
if ( $( this ).val() === '' ) {
$( this )
.addClass( 'wikieditor-toolbar-dialog-hint' )
.val( $( this ).data( 'tooltip' ) )
.data( 'tooltip-mode', true );
}
} )
.focus( function () {
if ( $( this ).val() === $( this ).data( 'tooltip' ) ) {
$( this )
.val( '' )
.removeClass( 'wikieditor-toolbar-dialog-hint' )
.data( 'tooltip-mode', false );
}
})
.bind( 'change', function () {
if ( $( this ).val() !== $( this ).data( 'tooltip' ) ) {
$( this )
.removeClass( 'wikieditor-toolbar-dialog-hint' )
.data( 'tooltip-mode', false );
}
})
.bind( 'blur', function () {
if ( $( this ).val() === '' ) {
$( this )
.addClass( 'wikieditor-toolbar-dialog-hint' )
.val( $( this ).data( 'tooltip' ) )
.data( 'tooltip-mode', true );
}
});
// Automatically copy the value of the internal link page title field to the link text field unless the
// user has changed the link text field - this is a convenience thing since most link texts are going to
// be the the same as the page title - Also change the internal/external radio button accordingly
$( '#wikieditor-toolbar-link-int-target' ).bind( 'change keydown paste cut', function () {
// $(this).val() is the old value, before the keypress - Defer this until $(this).val() has
// been updated
setTimeout( function () {
if ( isExternalLink( $( '#wikieditor-toolbar-link-int-target' ).val() ) ) {
$( '#wikieditor-toolbar-link-type-ext' ).prop( 'checked', true );
updateWidget( 'external' );
} else {
$( '#wikieditor-toolbar-link-type-int' ).prop( 'checked', true );
updateExistence();
}
/*jshint eqeqeq:false */
if ( $( '#wikieditor-toolbar-link-int-text' ).data( 'untouched' ) ) {
if ( $( '#wikieditor-toolbar-link-int-target' ).val() ==
$( '#wikieditor-toolbar-link-int-target' ).data( 'tooltip' )
) {
$( '#wikieditor-toolbar-link-int-text' )
.addClass( 'wikieditor-toolbar-dialog-hint' )
.val( $( '#wikieditor-toolbar-link-int-text' ).data( 'tooltip' ) )
.change();
} else {
$( '#wikieditor-toolbar-link-int-text' )
.val( $( '#wikieditor-toolbar-link-int-target' ).val() )
.change();
}
}
}, 0 );
});
$( '#wikieditor-toolbar-link-int-text' ).bind( 'change keydown paste cut', function () {
var oldVal = $(this).val();
var that = this;
setTimeout( function () {
if ( $(that).val() !== oldVal ) {
$(that).data( 'untouched', false );
}
}, 0 );
});
// Add images to the page existence widget, which will be shown mutually exclusively to communicate if
// the page exists, does not exist or the title is invalid (like if it contains a | character)
var existsMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-exists' );
var notexistsMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-notexists' );
var invalidMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-invalid' );
var externalMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-external' );
var loadingMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-loading' );
var disambigMsg = mw.msg( 'wikieditor-toolbar-tool-link-int-target-status-disambig' );
$( '#wikieditor-toolbar-link-int-target-status' )
.append( $( '