r68742 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68741‎ | r68742 | r68743 >
Date:20:59, 29 June 2010
Author:adam
Status:deferred
Tags:
Comment:
Adding wikiEditor, and fixing positioning of the load indicator
Modified paths:
  • /trunk/extensions/LiquidThreads/classes/View.php (modified) (history)
  • /trunk/extensions/LiquidThreads/js (added) (history)
  • /trunk/extensions/LiquidThreads/js/lqt.toolbar.js (added) (history)
  • /trunk/extensions/LiquidThreads/lqt.css (modified) (history)
  • /trunk/extensions/LiquidThreads/lqt.js (modified) (history)

Diff [purge]

Index: trunk/extensions/LiquidThreads/lqt.css
@@ -474,3 +474,7 @@
475475 .lqt-new-messages {
476476 table-layout: fixed;
477477 }
 478+.lqt-loader {
 479+ top: 15px;
 480+ height: 32px;
 481+}
Index: trunk/extensions/LiquidThreads/classes/View.php
@@ -1211,6 +1211,7 @@
12121212 $wgOut->addScriptFile( "$basePath/jquery/jquery.autogrow.js" );
12131213
12141214 $wgOut->addScriptFile( "$basePath/lqt.js" );
 1215+ $wgOut->addScriptFile( "$basePath/js/lqt.toolbar.js" );
12151216 $wgOut->addExtensionStyle( "$basePath/lqt.css?{$wgStyleVersion}" );
12161217
12171218 self::$stylesAndScriptsDone = true;
Index: trunk/extensions/LiquidThreads/lqt.js
@@ -1,7 +1,7 @@
22 // Prototype in string.trim on browsers that haven't yet implemented
33 if ( typeof String.prototype.trim !== "function" )
44 String.prototype.trim = function() { return this.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
5 -
 5+var wgWikiEditorIconVersion = 0;
66 var liquidThreads = {
77 currentReplyThread : null,
88 currentToolbar : null,
@@ -19,7 +19,8 @@
2020 var container = $j(target).closest('.lqt_thread')[0];
2121 var thread_id = $j(this).data('thread-id');
2222
23 - if (thread_id == liquidThreads.currentReplyThread) {
 23+ // hide the form for this thread if it's currently being shown
 24+ if ( thread_id == liquidThreads.currentReplyThread && $( '#wpTextbox1' ).is( ':visible' ) ) {
2425 liquidThreads.cancelEdit({});
2526 return;
2627 }
@@ -117,7 +118,7 @@
118119
119120 var isIE7 = $j.browser.msie && $j.browser.version.substr(0,1) == '7';
120121
121 - var loadSpinner = $j('<div class="mw-ajax-loader"/>');
 122+ var loadSpinner = $j('<div class="mw-ajax-loader lqt-loader"/>');
122123 $j(container).before( loadSpinner );
123124
124125 var finishShow = function() {
@@ -170,9 +171,13 @@
171172 $j(container).find('#wpTextbox1').attr( 'rows', 12 );
172173 $j(container).find('#wpDiff').hide();
173174
174 - // Add toolbar
175 - mwSetupToolbar();
176 -
 175+ if ( $j.fn.wikiEditor && $j.wikiEditor.isSupported( $j.wikiEditor.modules.toolbar ) ) {
 176+ // Add wikiEditor toolbar
 177+ $j( '#wpTextbox1' ).wikiEditor( 'addModule', { 'toolbar': liquidThreads.toolbar.config } );
 178+ } else {
 179+ // Add old toolbar
 180+ mwSetupToolbar()
 181+ }
177182 currentFocused = $j(container).find('#wpTextbox1');
178183 $j(container).find('#wpTextbox1,#wpSummary').focus(
179184 function() {
Index: trunk/extensions/LiquidThreads/js/lqt.toolbar.js
@@ -0,0 +1,2719 @@
 2+/* JavaScript config for the WikiEditor Toolbar module */
 3+
 4+liquidThreads.toolbar = {
 5+ config: {
 6+ // Main section
 7+ 'main': {
 8+ type: 'toolbar',
 9+ groups: {
 10+ 'format': {
 11+ tools: {
 12+ 'bold': {
 13+ labelMsg: 'wikieditor-toolbar-tool-bold',
 14+ type: 'button',
 15+ offset: {
 16+ 'default': [2, -574],
 17+ 'en': [2, -142],
 18+ 'cs': [2, -142],
 19+ 'de': [2, -214],
 20+ 'fr': [2, -286],
 21+ 'es': [2, -358],
 22+ 'he': [2, -142],
 23+ 'it': [2, -286],
 24+ 'nl': [2, -502],
 25+ 'pt': [2, -358],
 26+ 'pt-br': [2, -358],
 27+ 'pl': [2, -142]
 28+ },
 29+ icon: {
 30+ 'default': 'format-bold.png',
 31+ 'en': 'format-bold-B.png',
 32+ 'cs': 'format-bold-B.png',
 33+ 'de': 'format-bold-F.png',
 34+ 'fr': 'format-bold-G.png',
 35+ 'es': 'format-bold-N.png',
 36+ 'he': 'format-bold-B.png',
 37+ 'it': 'format-bold-G.png',
 38+ 'ka': 'format-bold-ka.png',
 39+ 'nl': 'format-bold-V.png',
 40+ 'pt': 'format-bold-N.png',
 41+ 'pt-br': 'format-bold-N.png',
 42+ 'pl': 'format-bold-B.png',
 43+ 'ru': 'format-bold-ru.png'
 44+ },
 45+ action: {
 46+ type: 'encapsulate',
 47+ options: {
 48+ pre: "'''",
 49+ periMsg: 'wikieditor-toolbar-tool-bold-example',
 50+ post: "'''"
 51+ }
 52+ }
 53+ },
 54+ 'italic': {
 55+ section: 'main',
 56+ group: 'format',
 57+ id: 'italic',
 58+ labelMsg: 'wikieditor-toolbar-tool-italic',
 59+ type: 'button',
 60+ offset: {
 61+ 'default': [2, -718],
 62+ 'en': [2, -862],
 63+ 'cs': [2, -862],
 64+ 'de': [2, -934],
 65+ 'fr': [2, -862],
 66+ 'es': [2, -790],
 67+ 'he': [2, -862],
 68+ 'it': [2, -790],
 69+ 'nl': [2, -790],
 70+ 'pt': [2, -862],
 71+ 'pt-br': [2, -862],
 72+ 'pl': [2, -862],
 73+ 'ru': [2, -934]
 74+ },
 75+ icon: {
 76+ 'default': 'format-italic.png',
 77+ 'en': 'format-italic-I.png',
 78+ 'cs': 'format-italic-I.png',
 79+ 'de': 'format-italic-K.png',
 80+ 'fr': 'format-italic-I.png',
 81+ 'es': 'format-italic-C.png',
 82+ 'he': 'format-italic-I.png',
 83+ 'it': 'format-italic-C.png',
 84+ 'ka': 'format-italic-ka.png',
 85+ 'nl': 'format-italic-C.png',
 86+ 'pt': 'format-italic-I.png',
 87+ 'pt-br': 'format-italic-I.png',
 88+ 'pl': 'format-italic-I.png',
 89+ 'ru': 'format-italic-K.png'
 90+ },
 91+ action: {
 92+ type: 'encapsulate',
 93+ options: {
 94+ pre: "''",
 95+ periMsg: 'wikieditor-toolbar-tool-italic-example',
 96+ post: "''"
 97+ }
 98+ }
 99+ }
 100+ }
 101+ },
 102+ 'insert': {
 103+ tools: {
 104+ 'xlink': {
 105+ labelMsg: 'wikieditor-toolbar-tool-xlink',
 106+ type: 'button',
 107+ icon: 'insert-xlink.png',
 108+ offset: [-70, 2],
 109+ filters: [ '#wpTextbox1:not(.toolbar-dialogs)' ],
 110+ action: {
 111+ type: 'encapsulate',
 112+ options: {
 113+ pre: "[",
 114+ periMsg: 'wikieditor-toolbar-tool-xlink-example',
 115+ post: "]"
 116+ }
 117+ }
 118+ },
 119+ 'ilink': {
 120+ labelMsg: 'wikieditor-toolbar-tool-ilink',
 121+ type: 'button',
 122+ icon: 'insert-ilink.png',
 123+ offset: [2, -1582],
 124+ filters: [ '#wpTextbox1:not(.toolbar-dialogs)' ],
 125+ action: {
 126+ type: 'encapsulate',
 127+ options: {
 128+ pre: "[[",
 129+ periMsg: 'wikieditor-toolbar-tool-ilink-example',
 130+ post: "]]"
 131+ }
 132+ }
 133+ },
 134+ 'linkCGD': {
 135+ labelMsg: 'wikieditor-toolbar-tool-link',
 136+ type: 'button',
 137+ icon: 'insert-link.png',
 138+ offset: [2, -1654],
 139+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 140+ action: {
 141+ type: 'dialog',
 142+ module: 'insert-link'
 143+ }
 144+ },
 145+ 'file': {
 146+ labelMsg: 'wikieditor-toolbar-tool-file',
 147+ type: 'button',
 148+ icon: 'insert-file.png',
 149+ offset: [2, -1438],
 150+ action: {
 151+ type: 'encapsulate',
 152+ options: {
 153+ // FIXME: Why the hell was this done this way?
 154+ preMsg: [ 'wikieditor-toolbar-tool-file-pre', '[[' ],
 155+ periMsg: 'wikieditor-toolbar-tool-file-example',
 156+ post: "]]"
 157+ }
 158+ }
 159+ },
 160+ 'referenceCGD': {
 161+ labelMsg: 'wikieditor-toolbar-tool-reference',
 162+ type: 'button',
 163+ icon: 'insert-reference.png',
 164+ offset: [2, -1798],
 165+ filters: [ 'body.ns-subject', '#wpTextbox1.toolbar-dialogs' ],
 166+ action: {
 167+ type: 'dialog',
 168+ module: 'insert-reference'
 169+ }
 170+ },
 171+ 'reference': {
 172+ labelMsg: 'wikieditor-toolbar-tool-reference',
 173+ filters: [ 'body.ns-subject', '#wpTextbox1:not(.toolbar-dialogs)' ],
 174+ type: 'button',
 175+ offset: [2, -1798],
 176+ icon: 'insert-reference.png',
 177+ action: {
 178+ type: 'encapsulate',
 179+ options: {
 180+ pre: "<ref>",
 181+ periMsg: 'wikieditor-toolbar-tool-reference-example',
 182+ post: "</ref>"
 183+ }
 184+ }
 185+ },
 186+ 'signature': {
 187+ labelMsg: 'wikieditor-toolbar-tool-signature',
 188+ filters: [ 'body:not(.ns-0)' ],
 189+ type: 'button',
 190+ offset: [2, -1872],
 191+ icon: 'insert-signature.png',
 192+ action: {
 193+ type: 'encapsulate',
 194+ options: {
 195+ post: "--~~~~"
 196+ }
 197+ }
 198+ }
 199+ }
 200+ }
 201+ }
 202+ }
 203+ },
 204+ 'dialogs': {
 205+ 'insert-link': {
 206+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 207+ titleMsg: 'wikieditor-toolbar-tool-link-title',
 208+ id: 'wikieditor-toolbar-link-dialog',
 209+ html: '\
 210+ <fieldset>\
 211+ <div class="wikieditor-toolbar-field-wrapper">\
 212+ <label for="wikieditor-toolbar-link-int-target" rel="wikieditor-toolbar-tool-link-int-target" id="wikieditor-toolbar-tool-link-int-target-label"></label>\
 213+ <div id="wikieditor-toolbar-link-int-target-status"></div>\
 214+ <input type="text" id="wikieditor-toolbar-link-int-target" />\
 215+ </div>\
 216+ <div class="wikieditor-toolbar-field-wrapper">\
 217+ <label for="wikieditor-toolbar-link-int-text" rel="wikieditor-toolbar-tool-link-int-text"></label>\
 218+ <input type="text" id="wikieditor-toolbar-link-int-text" />\
 219+ </div>\
 220+ <div class="wikieditor-toolbar-field-wrapper">\
 221+ <div class="wikieditor-toolbar-floated-field-wrapper">\
 222+ <input type="radio" id="wikieditor-toolbar-link-type-int" name="wikieditor-toolbar-link-type" selected />\
 223+ <label for="wikieditor-toolbar-link-type-int" rel="wikieditor-toolbar-tool-link-int"></label>\
 224+ </div>\
 225+ <div class="wikieditor-toolbar-floated-field-wrapper">\
 226+ <input type="radio" id="wikieditor-toolbar-link-type-ext" name="wikieditor-toolbar-link-type" />\
 227+ <label for="wikieditor-toolbar-link-type-ext" rel="wikieditor-toolbar-tool-link-ext"></label>\
 228+ </div>\
 229+ </div>\
 230+ </fieldset>',
 231+ init: function() {
 232+ function isExternalLink( s ) {
 233+ // The following things are considered to be external links:
 234+ // * Starts a URL protocol
 235+ // * Starts with www.
 236+ // All of these are potentially valid titles, and the latter two
 237+ // categories match about 6300 titles in enwiki's ns0. Out of 6.9M
 238+ // titles, that's 0.09%
 239+ if ( typeof arguments.callee.regex == 'undefined' ) {
 240+ // Cache the regex
 241+ arguments.callee.regex =
 242+ new RegExp( "^(" + wgUrlProtocols + "|www\\.)", 'i');
 243+ }
 244+ return s.match( arguments.callee.regex );
 245+ }
 246+ // Updates the status indicator above the target link
 247+ function updateWidget( status ) {
 248+ $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide();
 249+ $j( '#wikieditor-toolbar-link-int-target' ).parent()
 250+ .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' );
 251+ if ( status ) {
 252+ $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show();
 253+ $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status );
 254+ }
 255+ if ( status == 'invalid' ) {
 256+ $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
 257+ .attr( 'disabled', true )
 258+ .addClass( 'disabled' );
 259+ } else {
 260+ $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
 261+ .removeAttr('disabled')
 262+ .removeClass('disabled');
 263+ }
 264+ }
 265+ // Updates the UI to show if the page title being inputed by the user exists or not
 266+ // accepts parameter internal for bypassing external link detection
 267+ function updateExistence( internal ) {
 268+ // ensure the internal parameter is a boolean
 269+ if ( internal != true ) internal = false;
 270+ // Abort previous request
 271+ var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
 272+ if ( request ) {
 273+ request.abort();
 274+ }
 275+ var target = $j( '#wikieditor-toolbar-link-int-target' ).val();
 276+ var cache = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'existencecache' );
 277+ if ( cache[target] ) {
 278+ updateWidget( cache[target] );
 279+ return;
 280+ }
 281+ if ( target.replace( /^\s+$/,'' ) == '' ) {
 282+ // Hide the widget when the textbox is empty
 283+ updateWidget( false );
 284+ return;
 285+ }
 286+ // If the forced internal paremter was not true, check if the target is an external link
 287+ if ( !internal && isExternalLink( target ) ) {
 288+ updateWidget( 'external' );
 289+ return;
 290+ }
 291+ if ( target.indexOf( '|' ) != -1 ) {
 292+ // Title contains | , which means it's invalid
 293+ // but confuses the API. Show invalid and bypass API
 294+ updateWidget( 'invalid' );
 295+ return;
 296+ }
 297+ // Show loading spinner while waiting for the API to respond
 298+ updateWidget( 'loading' );
 299+ // Call the API to check page status, saving the request object so it can be aborted if necessary
 300+ $j( '#wikieditor-toolbar-link-int-target-status' ).data(
 301+ 'request',
 302+ $j.ajax( {
 303+ url: wgScriptPath + '/api.php',
 304+ dataType: 'json',
 305+ data: {
 306+ 'action': 'query',
 307+ 'indexpageids': '',
 308+ 'titles': target,
 309+ 'format': 'json'
 310+ },
 311+ success: function( data ) {
 312+ if ( !data ) {
 313+ // This happens in some weird cases
 314+ return;
 315+ }
 316+ var status;
 317+ if ( typeof data.query == 'undefined' ) {
 318+ status = 'invalid';
 319+ } else {
 320+ var page = data.query.pages[data.query.pageids[0]];
 321+ status = 'exists';
 322+ if ( typeof page.missing != 'undefined' )
 323+ status = 'notexists';
 324+ else if ( typeof page.invalid != 'undefined' )
 325+ status = 'invalid';
 326+ }
 327+ // Cache the status of the link target if the force internal parameter was not passed
 328+ if ( !internal ) cache[target] = status;
 329+ updateWidget( status );
 330+ }
 331+ } )
 332+ );
 333+ }
 334+ $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).click( function() {
 335+ if( $j( '#wikieditor-toolbar-link-type-ext' ).is( ':checked' ) ) {
 336+ // Abort previous request
 337+ var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
 338+ if ( request ) {
 339+ request.abort();
 340+ }
 341+ updateWidget( 'external' );
 342+ }
 343+ if( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) )
 344+ updateExistence( true );
 345+ });
 346+ // Set labels of tabs based on rel values
 347+ var u = mw.usability;
 348+ $j(this).find( '[rel]' ).each( function() {
 349+ $j(this).text( u.getMsg( $j(this).attr( 'rel' ) ) );
 350+ });
 351+ // Set tabindexes on form fields
 352+ $j.wikiEditor.modules.dialogs.fn.setTabindexes( $j(this).find( 'input' ).not( '[tabindex]' ) );
 353+ // Setup the tooltips in the textboxes
 354+ $j( '#wikieditor-toolbar-link-int-target' )
 355+ .data( 'tooltip', u.getMsg( 'wikieditor-toolbar-tool-link-int-target-tooltip' ) );
 356+ $j( '#wikieditor-toolbar-link-int-text' )
 357+ .data( 'tooltip', u.getMsg( 'wikieditor-toolbar-tool-link-int-text-tooltip' ) );
 358+ $j( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' )
 359+ .each( function() {
 360+ var tooltip = u.getMsg( $j( this ).attr( 'id' ) + '-tooltip' );
 361+ if ( $j( this ).val() == '' )
 362+ $j( this )
 363+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 364+ .val( $j( this ).data( 'tooltip' ) )
 365+ .data( 'tooltip-mode', true );
 366+ } )
 367+ .focus( function() {
 368+ if( $j( this ).val() == $j( this ).data( 'tooltip' ) ) {
 369+ $j( this )
 370+ .val( '' )
 371+ .removeClass( 'wikieditor-toolbar-dialog-hint' )
 372+ .data( 'tooltip-mode', false );
 373+ }
 374+ })
 375+ .bind( 'change', function() {
 376+ if ( $j( this ).val() != $j( this ).data( 'tooltip' ) ) {
 377+ $j( this )
 378+ .removeClass( 'wikieditor-toolbar-dialog-hint' )
 379+ .data( 'tooltip-mode', false );
 380+ }
 381+ })
 382+ .bind( 'blur', function() {
 383+ if ( $j( this ).val() == '' ) {
 384+ $j( this )
 385+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 386+ .val( $j( this ).data( 'tooltip' ) )
 387+ .data( 'tooltip-mode', true );
 388+ }
 389+ });
 390+
 391+ // Automatically copy the value of the internal link page title field to the link text field unless the user
 392+ // has changed the link text field - this is a convenience thing since most link texts are going to be the
 393+ // the same as the page title
 394+ // Also change the internal/external radio button accordingly
 395+ $j( '#wikieditor-toolbar-link-int-target' ).bind( 'change keydown paste cut', function() {
 396+ // $j(this).val() is the old value, before the keypress
 397+ // Defer this until $j(this).val() has been updated
 398+ setTimeout( function() {
 399+ if ( isExternalLink( $j( '#wikieditor-toolbar-link-int-target' ).val() ) ) {
 400+ $j( '#wikieditor-toolbar-link-type-ext' ).attr( 'checked', 'checked' );
 401+ updateWidget( 'external' );
 402+ } else {
 403+ $j( '#wikieditor-toolbar-link-type-int' ).attr( 'checked', 'checked' );
 404+ updateExistence();
 405+ }
 406+ if ( $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched' ) )
 407+ if ( $j( '#wikieditor-toolbar-link-int-target' ).val() ==
 408+ $j( '#wikieditor-toolbar-link-int-target' ).data( 'tooltip' ) ) {
 409+ $j( '#wikieditor-toolbar-link-int-text' )
 410+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 411+ .val( $j( '#wikieditor-toolbar-link-int-text' ).data( 'tooltip' ) )
 412+ .change();
 413+ } else {
 414+ $j( '#wikieditor-toolbar-link-int-text' )
 415+ .val( $j( '#wikieditor-toolbar-link-int-target' ).val() )
 416+ .change();
 417+ }
 418+ }, 0 );
 419+ });
 420+ $j( '#wikieditor-toolbar-link-int-text' ).bind( 'change keydown paste cut', function() {
 421+ var oldVal = $j(this).val();
 422+ var that = this;
 423+ setTimeout( function() {
 424+ if ( $j(that).val() != oldVal )
 425+ $j(that).data( 'untouched', false );
 426+ }, 0 );
 427+ });
 428+ // Add images to the page existence widget, which will be shown mutually exclusively to communicate if the
 429+ // page exists, does not exist or the title is invalid (like if it contains a | character)
 430+ var existsMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-exists' );
 431+ var notexistsMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-notexists' );
 432+ var invalidMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-invalid' );
 433+ var externalMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-external' );
 434+ var loadingMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-loading' );
 435+ $j( '#wikieditor-toolbar-link-int-target-status' )
 436+ .append( $j( '<div />' )
 437+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-exists' )
 438+ .append( existsMsg )
 439+ )
 440+ .append( $j( '<div />' )
 441+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-notexists' )
 442+ .append( notexistsMsg )
 443+ )
 444+ .append( $j( '<div />' )
 445+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-invalid' )
 446+ .append( invalidMsg )
 447+ )
 448+ .append( $j( '<div />' )
 449+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-external' )
 450+ .append( externalMsg )
 451+ )
 452+ .append( $j( '<div />' )
 453+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-loading' )
 454+ .append( $j( '<img />' ).attr( {
 455+ 'src': $j.wikiEditor.imgPath + 'dialogs/' + 'loading.gif',
 456+ 'alt': loadingMsg,
 457+ 'title': loadingMsg
 458+ } ) )
 459+ )
 460+ .data( 'existencecache', {} )
 461+ .children().hide();
 462+
 463+ $j( '#wikieditor-toolbar-link-int-target' )
 464+ .bind( 'keyup paste cut', function() {
 465+ // Cancel the running timer if applicable
 466+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' ) {
 467+ clearTimeout( $j(this).data( 'timerID' ) );
 468+ }
 469+ // Delay fetch for a while
 470+ // FIXME: Make 120 configurable elsewhere
 471+ var timerID = setTimeout( updateExistence, 120 );
 472+ $j(this).data( 'timerID', timerID );
 473+ } )
 474+ .change( function() {
 475+ // Cancel the running timer if applicable
 476+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' ) {
 477+ clearTimeout( $j(this).data( 'timerID' ) );
 478+ }
 479+ // Fetch right now
 480+ updateExistence();
 481+ } );
 482+
 483+ // Title suggestions
 484+ $j( '#wikieditor-toolbar-link-int-target' ).data( 'suggcache', {} ).suggestions( {
 485+ fetch: function( query ) {
 486+ var that = this;
 487+ var title = $j(this).val();
 488+
 489+ if ( isExternalLink( title ) || title.indexOf( '|' ) != -1 || title == '') {
 490+ $j(this).suggestions( 'suggestions', [] );
 491+ return;
 492+ }
 493+
 494+ var cache = $j(this).data( 'suggcache' );
 495+ if ( typeof cache[title] != 'undefined' ) {
 496+ $j(this).suggestions( 'suggestions', cache[title] );
 497+ return;
 498+ }
 499+
 500+ var request = $j.ajax( {
 501+ url: wgScriptPath + '/api.php',
 502+ data: {
 503+ 'action': 'opensearch',
 504+ 'search': title,
 505+ 'namespace': 0,
 506+ 'suggest': '',
 507+ 'format': 'json'
 508+ },
 509+ dataType: 'json',
 510+ success: function( data ) {
 511+ cache[title] = data[1];
 512+ $j(that).suggestions( 'suggestions', data[1] );
 513+ }
 514+ });
 515+ $j(this).data( 'request', request );
 516+ },
 517+ cancel: function() {
 518+ var request = $j(this).data( 'request' );
 519+ if ( request )
 520+ request.abort();
 521+ }
 522+ });
 523+ },
 524+ dialog: {
 525+ width: 500,
 526+ dialogClass: 'wikiEditor-toolbar-dialog',
 527+ buttons: {
 528+ 'wikieditor-toolbar-tool-link-insert': function() {
 529+ function escapeInternalText( s ) {
 530+ // FIXME: Should this escape [[ too? Seems to work without that
 531+ return s.replace( /(]{2,})/g, '<nowiki>$1</nowiki>' );
 532+ }
 533+ function escapeExternalTarget( s ) {
 534+ return s.replace( / /g, '%20' )
 535+ .replace( /\[/g, '%5B' )
 536+ .replace( /]/g, '%5D' );
 537+ }
 538+ function escapeExternalText( s ) {
 539+ // FIXME: Should this escape [ too? Seems to work without that
 540+ return s.replace( /(]+)/g, '<nowiki>$1</nowiki>' );
 541+ }
 542+ var insertText = '';
 543+ var whitespace = $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace' );
 544+ var target = $j( '#wikieditor-toolbar-link-int-target' ).val();
 545+ var text = $j( '#wikieditor-toolbar-link-int-text' ).val();
 546+ // check if the tooltips were passed as target or text
 547+ if ( $j( '#wikieditor-toolbar-link-int-target' ).data( 'tooltip-mode' ) )
 548+ target = "";
 549+ if ( $j( '#wikieditor-toolbar-link-int-text' ).data( 'tooltip-mode' ) )
 550+ text = "";
 551+ var u = mw.usability;
 552+ if ( target == '' ) {
 553+ alert( u.getMsg( 'wikieditor-toolbar-tool-link-empty' ) );
 554+ return;
 555+ }
 556+ if ( $j.trim( text ) == '' ) {
 557+ // [[Foo| ]] creates an invisible link
 558+ // Instead, generate [[Foo|]]
 559+ text = '';
 560+ }
 561+ if ( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) ) {
 562+ // FIXME: Exactly how fragile is this?
 563+ if ( $j( '#wikieditor-toolbar-link-int-target-status-invalid' ).is( ':visible' ) ) {
 564+ // Refuse to add links to invalid titles
 565+ alert( u.getMsg( 'wikieditor-toolbar-tool-link-int-invalid' ) );
 566+ return;
 567+ }
 568+
 569+ if ( target == text || !text.length )
 570+ insertText = '[[' + target + ']]';
 571+ else
 572+ insertText = '[[' + target + '|' + escapeInternalText( text ) + ']]';
 573+ } else {
 574+ // Prepend http:// if there is no protocol
 575+ if ( !target.match( /^[a-z]+:\/\/./ ) )
 576+ target = 'http://' + target;
 577+
 578+ // Detect if this is really an internal link in disguise
 579+ var match = target.match( $j(this).data( 'articlePathRegex' ) );
 580+ if ( match && !$j(this).data( 'ignoreLooksInternal' ) ) {
 581+ var buttons = { };
 582+ var that = this;
 583+ buttons[ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal-int' ) ] = function() {
 584+ $j( '#wikieditor-toolbar-link-int-target' ).val( match[1] ).change();
 585+ $j(this).dialog( 'close' );
 586+ };
 587+ buttons[ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal-ext' ) ] = function() {
 588+ $j(that).data( 'ignoreLooksInternal', true );
 589+ $j(that).closest( '.ui-dialog' ).find( 'button:first' ).click();
 590+ $j(that).data( 'ignoreLooksInternal', false );
 591+ $j(this).dialog( 'close' );
 592+ };
 593+ $j.wikiEditor.modules.dialogs.quickDialog(
 594+ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal', match[1] ),
 595+ { buttons: buttons }
 596+ );
 597+ return;
 598+ }
 599+
 600+ var escTarget = escapeExternalTarget( target );
 601+ var escText = escapeExternalText( text );
 602+
 603+ if ( escTarget == escText )
 604+ insertText = escTarget;
 605+ else if ( text == '' )
 606+ insertText = '[' + escTarget + ']';
 607+ else
 608+ insertText = '[' + escTarget + ' ' + escText + ']';
 609+ }
 610+ // Preserve whitespace in selection when replacing
 611+ if ( whitespace ) insertText = whitespace[0] + insertText + whitespace[1];
 612+ $j(this).dialog( 'close' );
 613+ $j.wikiEditor.modules.toolbar.fn.doAction( $j(this).data( 'context' ), {
 614+ type: 'replace',
 615+ options: {
 616+ pre: insertText
 617+ }
 618+ }, $j(this) );
 619+
 620+ // Blank form
 621+ $j( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' ).val( '' );
 622+ $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).attr( 'checked', '' );
 623+ },
 624+ 'wikieditor-toolbar-tool-link-cancel': function() {
 625+ // Clear any saved selection state
 626+ var context = $j(this).data( 'context' );
 627+ context.fn.restoreStuffForIE();
 628+ $j(this).dialog( 'close' );
 629+ }
 630+ },
 631+ open: function() {
 632+ // Cache the articlepath regex
 633+ $j(this).data( 'articlePathRegex', new RegExp(
 634+ '^' + RegExp.escape( wgServer + wgArticlePath )
 635+ .replace( /\\\$1/g, '(.*)' ) + '$'
 636+ ) );
 637+ // Pre-fill the text fields based on the current selection
 638+ var context = $j(this).data( 'context' );
 639+ // Restore and immediately save selection state, needed for inserting stuff later
 640+ context.fn.restoreStuffForIE();
 641+ context.fn.saveStuffForIE();
 642+ var selection = context.$textarea.textSelection( 'getSelection' );
 643+ $j( '#wikieditor-toolbar-link-int-target' ).focus();
 644+ // Trigger the change event, so the link status indicator is up to date
 645+ $j( '#wikieditor-toolbar-link-int-target' ).change();
 646+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ '', '' ] );
 647+ if ( selection != '' ) {
 648+ var target, text, type;
 649+ var matches;
 650+ if ( ( matches = selection.match( /^(\s*)\[\[([^\]\|]+)(\|([^\]\|]*))?\]\](\s*)$/ ) ) ) {
 651+ // [[foo|bar]] or [[foo]]
 652+ target = matches[2];
 653+ text = ( matches[4] ? matches[4] : matches[2] );
 654+ type = 'int';
 655+ // Preserve whitespace when replacing
 656+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[1], matches[5] ] );
 657+ } else if ( ( matches = selection.match( /^(\s*)\[([^\] ]+)( ([^\]]+))?\](\s*)$/ ) ) ) {
 658+ // [http://www.example.com foo] or [http://www.example.com]
 659+ target = matches[2];
 660+ text = ( matches[4] ? matches[4] : '' );
 661+ type = 'ext';
 662+ // Preserve whitespace when replacing
 663+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[1], matches[5] ] );
 664+ } else {
 665+ // Trim any leading and trailing whitespace from the selection,
 666+ // but preserve it when replacing
 667+ target = text = $j.trim( selection );
 668+ if ( target.length < selection.length ) {
 669+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [
 670+ selection.substr( 0, selection.indexOf( target.charAt( 0 ) ) ),
 671+ selection.substr(
 672+ selection.lastIndexOf( target.charAt( target.length - 1 ) ) + 1
 673+ ) ]
 674+ );
 675+ }
 676+ }
 677+
 678+ // Change the value by calling val() doesn't trigger the change event, so let's do that ourselves
 679+ if ( typeof text != 'undefined' )
 680+ $j( '#wikieditor-toolbar-link-int-text' ).val( text ).change();
 681+ if ( typeof target != 'undefined' )
 682+ $j( '#wikieditor-toolbar-link-int-target' ).val( target ).change();
 683+ if ( typeof type != 'undefined' )
 684+ $j( '#wikieditor-toolbar-link-' + type ).attr( 'checked', 'checked' );
 685+ }
 686+ $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched',
 687+ $j( '#wikieditor-toolbar-link-int-text' ).val() ==
 688+ $j( '#wikieditor-toolbar-link-int-target' ).val() ||
 689+ $j( '#wikieditor-toolbar-link-int-text' ).hasClass( 'wikieditor-toolbar-dialog-hint' )
 690+ );
 691+ $j( '#wikieditor-toolbar-link-int-target' ).suggestions();
 692+
 693+ //don't overwrite user's text
 694+ if( selection != '' ){
 695+ $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched', false );
 696+ }
 697+
 698+ $j( '#wikieditor-toolbar-link-int-text, #wikiedit-toolbar-link-int-target' )
 699+ .each( function() {
 700+ if ( $j(this).val() == '' )
 701+ $j(this).parent().find( 'label' ).show();
 702+ });
 703+
 704+ if ( !( $j(this).data( 'dialogkeypressset' ) ) ) {
 705+ $j(this).data( 'dialogkeypressset', true );
 706+ // Execute the action associated with the first button
 707+ // when the user presses Enter
 708+ $j(this).closest( '.ui-dialog' ).keypress( function( e ) {
 709+ if ( ( e.keyCode || e.which ) == 13 ) {
 710+ var button = $j(this).data( 'dialogaction' ) || $j(this).find( 'button:first' );
 711+ button.click();
 712+ e.preventDefault();
 713+ }
 714+ });
 715+
 716+ // Make tabbing to a button and pressing
 717+ // Enter do what people expect
 718+ $j(this).closest( '.ui-dialog' ).find( 'button' ).focus( function() {
 719+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', this );
 720+ });
 721+ }
 722+ }
 723+ }
 724+ }
 725+ }
 726+};
 727+
 728+/* TODO: Get wikiEditor strings loading and then switch to this configuration
 729+
 730+liquidThreads.toolbar.config = {
 731+ // Main section
 732+ 'main': {
 733+ type: 'toolbar',
 734+ groups: {
 735+ 'format': {
 736+ tools: {
 737+ 'bold': {
 738+ labelMsg: 'wikieditor-toolbar-tool-bold',
 739+ type: 'button',
 740+ offset: {
 741+ 'default': [2, -574],
 742+ 'en': [2, -142],
 743+ 'cs': [2, -142],
 744+ 'de': [2, -214],
 745+ 'fr': [2, -286],
 746+ 'es': [2, -358],
 747+ 'he': [2, -142],
 748+ 'it': [2, -286],
 749+ 'nl': [2, -502],
 750+ 'pt': [2, -358],
 751+ 'pt-br': [2, -358],
 752+ 'pl': [2, -142]
 753+ },
 754+ icon: {
 755+ 'default': 'format-bold.png',
 756+ 'en': 'format-bold-B.png',
 757+ 'cs': 'format-bold-B.png',
 758+ 'de': 'format-bold-F.png',
 759+ 'fr': 'format-bold-G.png',
 760+ 'es': 'format-bold-N.png',
 761+ 'he': 'format-bold-B.png',
 762+ 'it': 'format-bold-G.png',
 763+ 'ka': 'format-bold-ka.png',
 764+ 'nl': 'format-bold-V.png',
 765+ 'pt': 'format-bold-N.png',
 766+ 'pt-br': 'format-bold-N.png',
 767+ 'pl': 'format-bold-B.png',
 768+ 'ru': 'format-bold-ru.png'
 769+ },
 770+ action: {
 771+ type: 'encapsulate',
 772+ options: {
 773+ pre: "'''",
 774+ periMsg: 'wikieditor-toolbar-tool-bold-example',
 775+ post: "'''"
 776+ }
 777+ }
 778+ },
 779+ 'italic': {
 780+ section: 'main',
 781+ group: 'format',
 782+ id: 'italic',
 783+ labelMsg: 'wikieditor-toolbar-tool-italic',
 784+ type: 'button',
 785+ offset: {
 786+ 'default': [2, -718],
 787+ 'en': [2, -862],
 788+ 'cs': [2, -862],
 789+ 'de': [2, -934],
 790+ 'fr': [2, -862],
 791+ 'es': [2, -790],
 792+ 'he': [2, -862],
 793+ 'it': [2, -790],
 794+ 'nl': [2, -790],
 795+ 'pt': [2, -862],
 796+ 'pt-br': [2, -862],
 797+ 'pl': [2, -862],
 798+ 'ru': [2, -934]
 799+ },
 800+ icon: {
 801+ 'default': 'format-italic.png',
 802+ 'en': 'format-italic-I.png',
 803+ 'cs': 'format-italic-I.png',
 804+ 'de': 'format-italic-K.png',
 805+ 'fr': 'format-italic-I.png',
 806+ 'es': 'format-italic-C.png',
 807+ 'he': 'format-italic-I.png',
 808+ 'it': 'format-italic-C.png',
 809+ 'ka': 'format-italic-ka.png',
 810+ 'nl': 'format-italic-C.png',
 811+ 'pt': 'format-italic-I.png',
 812+ 'pt-br': 'format-italic-I.png',
 813+ 'pl': 'format-italic-I.png',
 814+ 'ru': 'format-italic-K.png'
 815+ },
 816+ action: {
 817+ type: 'encapsulate',
 818+ options: {
 819+ pre: "''",
 820+ periMsg: 'wikieditor-toolbar-tool-italic-example',
 821+ post: "''"
 822+ }
 823+ }
 824+ }
 825+ }
 826+ },
 827+ 'insert': {
 828+ tools: {
 829+ 'xlink': {
 830+ labelMsg: 'wikieditor-toolbar-tool-xlink',
 831+ type: 'button',
 832+ icon: 'insert-xlink.png',
 833+ offset: [-70, 2],
 834+ filters: [ '#wpTextbox1:not(.toolbar-dialogs)' ],
 835+ action: {
 836+ type: 'encapsulate',
 837+ options: {
 838+ pre: "[",
 839+ periMsg: 'wikieditor-toolbar-tool-xlink-example',
 840+ post: "]"
 841+ }
 842+ }
 843+ },
 844+ 'ilink': {
 845+ labelMsg: 'wikieditor-toolbar-tool-ilink',
 846+ type: 'button',
 847+ icon: 'insert-ilink.png',
 848+ offset: [2, -1582],
 849+ filters: [ '#wpTextbox1:not(.toolbar-dialogs)' ],
 850+ action: {
 851+ type: 'encapsulate',
 852+ options: {
 853+ pre: "[[",
 854+ periMsg: 'wikieditor-toolbar-tool-ilink-example',
 855+ post: "]]"
 856+ }
 857+ }
 858+ },
 859+ 'linkCGD': {
 860+ labelMsg: 'wikieditor-toolbar-tool-link',
 861+ type: 'button',
 862+ icon: 'insert-link.png',
 863+ offset: [2, -1654],
 864+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 865+ action: {
 866+ type: 'dialog',
 867+ module: 'insert-link'
 868+ }
 869+ },
 870+ 'file': {
 871+ labelMsg: 'wikieditor-toolbar-tool-file',
 872+ type: 'button',
 873+ icon: 'insert-file.png',
 874+ offset: [2, -1438],
 875+ action: {
 876+ type: 'encapsulate',
 877+ options: {
 878+ // FIXME: Why the hell was this done this way?
 879+ preMsg: [ 'wikieditor-toolbar-tool-file-pre', '[[' ],
 880+ periMsg: 'wikieditor-toolbar-tool-file-example',
 881+ post: "]]"
 882+ }
 883+ }
 884+ },
 885+ 'referenceCGD': {
 886+ labelMsg: 'wikieditor-toolbar-tool-reference',
 887+ type: 'button',
 888+ icon: 'insert-reference.png',
 889+ offset: [2, -1798],
 890+ filters: [ 'body.ns-subject', '#wpTextbox1.toolbar-dialogs' ],
 891+ action: {
 892+ type: 'dialog',
 893+ module: 'insert-reference'
 894+ }
 895+ },
 896+ 'reference': {
 897+ labelMsg: 'wikieditor-toolbar-tool-reference',
 898+ filters: [ 'body.ns-subject', '#wpTextbox1:not(.toolbar-dialogs)' ],
 899+ type: 'button',
 900+ offset: [2, -1798],
 901+ icon: 'insert-reference.png',
 902+ action: {
 903+ type: 'encapsulate',
 904+ options: {
 905+ pre: "<ref>",
 906+ periMsg: 'wikieditor-toolbar-tool-reference-example',
 907+ post: "</ref>"
 908+ }
 909+ }
 910+ },
 911+ 'signature': {
 912+ labelMsg: 'wikieditor-toolbar-tool-signature',
 913+ filters: [ 'body:not(.ns-0)' ],
 914+ type: 'button',
 915+ offset: [2, -1872],
 916+ icon: 'insert-signature.png',
 917+ action: {
 918+ type: 'encapsulate',
 919+ options: {
 920+ post: "--~~~~"
 921+ }
 922+ }
 923+ }
 924+ }
 925+ }
 926+ }
 927+ },
 928+ // Format section
 929+ 'advanced': {
 930+ labelMsg: 'wikieditor-toolbar-section-advanced',
 931+ type: 'toolbar',
 932+ groups: {
 933+ 'heading': {
 934+ tools: {
 935+ 'heading': {
 936+ labelMsg: 'wikieditor-toolbar-tool-heading',
 937+ type: 'select',
 938+ list: {
 939+ 'heading-2' : {
 940+ labelMsg: 'wikieditor-toolbar-tool-heading-2',
 941+ action: {
 942+ type: 'encapsulate',
 943+ options: {
 944+ pre: '== ',
 945+ periMsg: 'wikieditor-toolbar-tool-heading-example',
 946+ post: ' ==',
 947+ regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
 948+ regexReplace: "\$1==\$3==\$4",
 949+ ownline: true
 950+ }
 951+ }
 952+ },
 953+ 'heading-3' : {
 954+ labelMsg: 'wikieditor-toolbar-tool-heading-3',
 955+ action: {
 956+ type: 'encapsulate',
 957+ options: {
 958+ pre: '=== ',
 959+ periMsg: 'wikieditor-toolbar-tool-heading-example',
 960+ post: ' ===',
 961+ regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
 962+ regexReplace: "\$1===\$3===\$4",
 963+ ownline: true
 964+ }
 965+ }
 966+ },
 967+ 'heading-4' : {
 968+ labelMsg: 'wikieditor-toolbar-tool-heading-4',
 969+ action: {
 970+ type: 'encapsulate',
 971+ options: {
 972+ pre: '==== ',
 973+ periMsg: 'wikieditor-toolbar-tool-heading-example',
 974+ post: ' ====',
 975+ regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
 976+ regexReplace: "\$1====\$3====\$4",
 977+ ownline: true
 978+ }
 979+ }
 980+ },
 981+ 'heading-5' : {
 982+ labelMsg: 'wikieditor-toolbar-tool-heading-5',
 983+ action: {
 984+ type: 'encapsulate',
 985+ options: {
 986+ pre: '===== ',
 987+ periMsg: 'wikieditor-toolbar-tool-heading-example',
 988+ post: ' =====',
 989+ regex: /^(\s*)(={1,6})(.*?)\2(\s*)$/,
 990+ regexReplace: "\$1=====\$3=====\$4",
 991+ ownline: true
 992+ }
 993+ }
 994+ }
 995+ }
 996+ }
 997+ }
 998+ },
 999+ 'format': {
 1000+ labelMsg: 'wikieditor-toolbar-group-format',
 1001+ tools: {
 1002+ 'ulist': {
 1003+ labelMsg: 'wikieditor-toolbar-tool-ulist',
 1004+ type: 'button',
 1005+ icon: 'format-ulist.png',
 1006+ offset: [2, -1366],
 1007+ action: {
 1008+ type: 'encapsulate',
 1009+ options: {
 1010+ pre: "* ",
 1011+ periMsg: 'wikieditor-toolbar-tool-ulist-example',
 1012+ post: "",
 1013+ ownline: true
 1014+ }
 1015+ }
 1016+ },
 1017+ 'olist': {
 1018+ labelMsg: 'wikieditor-toolbar-tool-olist',
 1019+ type: 'button',
 1020+ icon: 'format-olist.png',
 1021+ offset: [2, -1078],
 1022+ action: {
 1023+ type: 'encapsulate',
 1024+ options: {
 1025+ pre: "# ",
 1026+ periMsg: 'wikieditor-toolbar-tool-olist-example',
 1027+ post: "",
 1028+ ownline: true
 1029+ }
 1030+ }
 1031+ },
 1032+ 'indent': {
 1033+ labelMsg: 'wikieditor-toolbar-tool-indent',
 1034+ type: 'button',
 1035+ icon: 'format-indent.png',
 1036+ offset: [2, -646],
 1037+ action: {
 1038+ type: 'encapsulate',
 1039+ options: {
 1040+ pre: ":",
 1041+ periMsg: 'wikieditor-toolbar-tool-indent-example',
 1042+ post: "",
 1043+ ownline: true,
 1044+ splitlines: true
 1045+ }
 1046+ }
 1047+ },
 1048+ 'nowiki': {
 1049+ labelMsg: 'wikieditor-toolbar-tool-nowiki',
 1050+ type: 'button',
 1051+ icon: 'insert-nowiki.png',
 1052+ offset: [-70, -70],
 1053+ action: {
 1054+ type: 'encapsulate',
 1055+ options: {
 1056+ pre: "<nowiki>",
 1057+ periMsg: 'wikieditor-toolbar-tool-nowiki-example',
 1058+ post: "</nowiki>"
 1059+ }
 1060+ }
 1061+ },
 1062+ 'newline': {
 1063+ labelMsg: 'wikieditor-toolbar-tool-newline',
 1064+ type: 'button',
 1065+ icon: 'insert-newline.png',
 1066+ offset: [2, -1726],
 1067+ action: {
 1068+ type: 'encapsulate',
 1069+ options: {
 1070+ pre: "<br />\n"
 1071+ }
 1072+ }
 1073+ }
 1074+ }
 1075+ },
 1076+ 'size': {
 1077+ tools: {
 1078+ 'big': {
 1079+ labelMsg: 'wikieditor-toolbar-tool-big',
 1080+ type: 'button',
 1081+ icon: 'format-big.png',
 1082+ offset: [2, 2],
 1083+ action: {
 1084+ type: 'encapsulate',
 1085+ options: {
 1086+ pre: "<big>",
 1087+ periMsg: 'wikieditor-toolbar-tool-big-example',
 1088+ post: "</big>"
 1089+ }
 1090+ }
 1091+ },
 1092+ 'small': {
 1093+ labelMsg: 'wikieditor-toolbar-tool-small',
 1094+ type: 'button',
 1095+ icon: 'format-small.png',
 1096+ offset: [2, -1150],
 1097+ action: {
 1098+ type: 'encapsulate',
 1099+ options: {
 1100+ pre: "<small>",
 1101+ periMsg: 'wikieditor-toolbar-tool-small-example',
 1102+ post: "</small>"
 1103+ }
 1104+ }
 1105+ },
 1106+ 'superscript': {
 1107+ labelMsg: 'wikieditor-toolbar-tool-superscript',
 1108+ type: 'button',
 1109+ icon: 'format-superscript.png',
 1110+ offset: [2, -1294],
 1111+ action: {
 1112+ type: 'encapsulate',
 1113+ options: {
 1114+ pre: "<sup>",
 1115+ periMsg: 'wikieditor-toolbar-tool-superscript-example',
 1116+ post: "</sup>"
 1117+ }
 1118+ }
 1119+ },
 1120+ 'subscript': {
 1121+ labelMsg: 'wikieditor-toolbar-tool-subscript',
 1122+ type: 'button',
 1123+ icon: 'format-subscript.png',
 1124+ offset: [2, -1222],
 1125+ action: {
 1126+ type: 'encapsulate',
 1127+ options: {
 1128+ pre: "<sub>",
 1129+ periMsg: 'wikieditor-toolbar-tool-subscript-example',
 1130+ post: "</sub>"
 1131+ }
 1132+ }
 1133+ }
 1134+ }
 1135+ },
 1136+ 'insert': {
 1137+ labelMsg: 'wikieditor-toolbar-group-insert',
 1138+ tools: {
 1139+ 'gallery': {
 1140+ labelMsg: 'wikieditor-toolbar-tool-gallery',
 1141+ type: 'button',
 1142+ icon: 'insert-gallery.png',
 1143+ offset: [2, -1510],
 1144+ action: {
 1145+ type: 'encapsulate',
 1146+ options: {
 1147+ pre: "<gallery>\n",
 1148+ periMsg: 'wikieditor-toolbar-tool-gallery-example',
 1149+ post: "\n</gallery>",
 1150+ ownline: true
 1151+ }
 1152+ }
 1153+ },
 1154+ 'tableCGD': {
 1155+ labelMsg: 'wikieditor-toolbar-tool-table',
 1156+ type: 'button',
 1157+ icon: 'insert-table.png',
 1158+ offset: [2, -1942],
 1159+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 1160+ action: {
 1161+ type: 'dialog',
 1162+ module: 'insert-table'
 1163+ }
 1164+ },
 1165+ 'table': {
 1166+ labelMsg: 'wikieditor-toolbar-tool-table',
 1167+ type: 'button',
 1168+ icon: 'insert-table.png',
 1169+ offset: [2, -1942],
 1170+ filters: [ '#wpTextbox1:not(.toolbar-dialogs)' ],
 1171+ action: {
 1172+ type: 'encapsulate',
 1173+ options: {
 1174+ pre: "{| class=\"wikitable\" border=\"1\"\n|",
 1175+ periMsg: 'wikieditor-toolbar-tool-table-example-old',
 1176+ post: "\n|}",
 1177+ ownline: true
 1178+ }
 1179+ }
 1180+ },
 1181+ 'redirect': {
 1182+ labelMsg: 'wikieditor-toolbar-tool-redirect',
 1183+ type: 'button',
 1184+ icon: 'insert-redirect.png',
 1185+ offset: [-70, -142],
 1186+ action: {
 1187+ type: 'encapsulate',
 1188+ options: {
 1189+ pre: "#REDIRECT [[",
 1190+ periMsg: 'wikieditor-toolbar-tool-redirect-example',
 1191+ post: "]]",
 1192+ ownline: true
 1193+ }
 1194+ }
 1195+ }
 1196+ }
 1197+ },
 1198+ 'search': {
 1199+ tools: {
 1200+ 'replace': {
 1201+ labelMsg: 'wikieditor-toolbar-tool-replace',
 1202+ type: 'button',
 1203+ icon: 'search-replace.png',
 1204+ offset: [-70, -214],
 1205+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 1206+ action: {
 1207+ type: 'dialog',
 1208+ module: 'search-and-replace'
 1209+ }
 1210+ }
 1211+ }
 1212+ }
 1213+ }
 1214+ },
 1215+ 'characters': {
 1216+ labelMsg: 'wikieditor-toolbar-section-characters',
 1217+ type: 'booklet',
 1218+ deferLoad: true,
 1219+ pages: {
 1220+ 'latin': {
 1221+ 'labelMsg': 'wikieditor-toolbar-characters-page-latin',
 1222+ 'layout': 'characters',
 1223+ 'characters': [
 1224+ "\u00c1", "\u00e1", "\u00c0", "\u00e0", "\u00c2", "\u00e2", "\u00c4", "\u00e4", "\u00c3", "\u00e3",
 1225+ "\u01cd", "\u01ce", "\u0100", "\u0101", "\u0102", "\u0103", "\u0104", "\u0105", "\u00c5", "\u00e5",
 1226+ "\u0106", "\u0107", "\u0108", "\u0109", "\u00c7", "\u00e7", "\u010c", "\u010d", "\u010a", "\u010b",
 1227+ "\u0110", "\u0111", "\u010e", "\u010f", "\u00c9", "\u00e9", "\u00c8", "\u00e8", "\u00ca", "\u00ea",
 1228+ "\u00cb", "\u00eb", "\u011a", "\u011b", "\u0112", "\u0113", "\u0114", "\u0115", "\u0116", "\u0117",
 1229+ "\u0118", "\u0119", "\u011c", "\u011d", "\u0122", "\u0123", "\u011e", "\u011f", "\u0120", "\u0121",
 1230+ "\u0124", "\u0125", "\u0126", "\u0127", "\u00cd", "\u00ed", "\u00cc", "\u00ec", "\u00ce", "\u00ee",
 1231+ "\u00cf", "\u00ef", "\u0128", "\u0129", "\u01cf", "\u01d0", "\u012a", "\u012b", "\u012c", "\u012d",
 1232+ "\u0130", "\u0131", "\u012e", "\u012f", "\u0134", "\u0135", "\u0136", "\u0137", "\u0139", "\u013a",
 1233+ "\u013b", "\u013c", "\u013d", "\u013e", "\u0141", "\u0142", "\u013f", "\u0140", "\u0143", "\u0144",
 1234+ "\u00d1", "\u00f1", "\u0145", "\u0146", "\u0147", "\u0148", "\u00d3", "\u00f3", "\u00d2", "\u00f2",
 1235+ "\u00d4", "\u00f4", "\u00d6", "\u00f6", "\u00d5", "\u00f5", "\u01d1", "\u01d2", "\u014c", "\u014d",
 1236+ "\u014e", "\u014f", "\u01ea", "\u01eb", "\u0150", "\u0151", "\u0154", "\u0155", "\u0156", "\u0157",
 1237+ "\u0158", "\u0159", "\u015a", "\u015b", "\u015c", "\u015d", "\u015e", "\u015f", "\u0160", "\u0161",
 1238+ "\u0162", "\u0163", "\u0164", "\u0165", "\u00da", "\u00fa", "\u00d9", "\u00f9", "\u00db", "\u00fb",
 1239+ "\u00dc", "\u00fc", "\u0168", "\u0169", "\u016e", "\u016f", "\u01d3", "\u01d4", "\u016a", "\u016b",
 1240+ "\u01d6", "\u01d8", "\u01da", "\u01dc", "\u016c", "\u016d", "\u0172", "\u0173", "\u0170", "\u0171",
 1241+ "\u0174", "\u0175", "\u00dd", "\u00fd", "\u0176", "\u0177", "\u0178", "\u00ff", "\u0232", "\u0233",
 1242+ "\u0179", "\u017a", "\u017d", "\u017e", "\u017b", "\u017c", "\u00c6", "\u00e6", "\u01e2", "\u01e3",
 1243+ "\u00d8", "\u00f8", "\u0152", "\u0153", "\u00df", "\u00f0", "\u00de", "\u00fe", "\u018f", "\u0259"
 1244+ ]
 1245+ },
 1246+ 'latinextended': {
 1247+ 'labelMsg': 'wikieditor-toolbar-characters-page-latinextended',
 1248+ 'layout': 'characters',
 1249+ 'characters': [
 1250+ "\u1e00", "\u1e01", "\u1e9a", "\u1ea0", "\u1ea1", "\u1ea2", "\u1ea3", "\u1ea4", "\u1ea5", "\u1ea6",
 1251+ "\u1ea7", "\u1ea8", "\u1ea9", "\u1eaa", "\u1eab", "\u1eac", "\u1ead", "\u1eae", "\u1eaf", "\u1eb0",
 1252+ "\u1eb1", "\u1eb2", "\u1eb3", "\u1eb4", "\u1eb5", "\u1eb6", "\u1eb7", "\u1e02", "\u1e03", "\u1e04",
 1253+ "\u1e05", "\u1e06", "\u1e07", "\u1e08", "\u1e09", "\u1e0a", "\u1e0b", "\u1e0c", "\u1e0d", "\u1e0e",
 1254+ "\u1e0f", "\u1e10", "\u1e11", "\u1e12", "\u1e13", "\u1e14", "\u1e15", "\u1e16", "\u1e17", "\u1e18",
 1255+ "\u1e19", "\u1e1a", "\u1e1b", "\u1e1c", "\u1e1d", "\u1eb8", "\u1eb9", "\u1eba", "\u1ebb", "\u1ebc",
 1256+ "\u1ebd", "\u1ebe", "\u1ebf", "\u1ec0", "\u1ec1", "\u1ec2", "\u1ec3", "\u1ec4", "\u1ec5", "\u1ec6",
 1257+ "\u1ec7", "\u1e1e", "\u1e1f", "\u1e20", "\u1e21", "\u1e22", "\u1e23", "\u1e24", "\u1e25", "\u1e26",
 1258+ "\u1e27", "\u1e28", "\u1e29", "\u1e2a", "\u1e2b", "\u1e96", "\u1e2c", "\u1e2d", "\u1e2e", "\u1e2f",
 1259+ "\u1ec8", "\u1ec9", "\u1eca", "\u1ecb", "\u1e30", "\u1e31", "\u1e32", "\u1e33", "\u1e34", "\u1e35",
 1260+ "\u1e36", "\u1e37", "\u1e38", "\u1e39", "\u1e3a", "\u1e3b", "\u1e3c", "\u1e3d", "\u1efa", "\u1efb",
 1261+ "\u1e3e", "\u1e3f", "\u1e40", "\u1e41", "\u1e42", "\u1e43", "\u1e44", "\u1e45", "\u1e46", "\u1e47",
 1262+ "\u1e48", "\u1e49", "\u1e4a", "\u1e4b", "\u1e4c", "\u1e4d", "\u1e4e", "\u1e4f", "\u1e50", "\u1e51",
 1263+ "\u1e52", "\u1e53", "\u1ecc", "\u1ecd", "\u1ece", "\u1ecf", "\u1ed0", "\u1ed1", "\u1ed2", "\u1ed3",
 1264+ "\u1ed4", "\u1ed5", "\u1ed6", "\u1ed7", "\u1ed8", "\u1ed9", "\u1eda", "\u1edb", "\u1edc", "\u1edd",
 1265+ "\u1ede", "\u1edf", "\u1ee0", "\u1ee1", "\u1ee2", "\u1ee3", "\u1e54", "\u1e55", "\u1e56", "\u1e57",
 1266+ "\u1e58", "\u1e59", "\u1e5a", "\u1e5b", "\u1e5c", "\u1e5d", "\u1e5e", "\u1e5f", "\u1e60", "\u1e61",
 1267+ "\u1e9b", "\u1e62", "\u1e63", "\u1e64", "\u1e65", "\u1e66", "\u1e67", "\u1e68", "\u1e69", "\u1e9c",
 1268+ "\u1e9d", "\u1e6a", "\u1e6b", "\u1e6c", "\u1e6d", "\u1e6e", "\u1e6f", "\u1e70", "\u1e71", "\u1e97",
 1269+ "\u1e72", "\u1e73", "\u1e74", "\u1e75", "\u1e76", "\u1e77", "\u1e78", "\u1e79", "\u1e7a", "\u1e7b",
 1270+ "\u1ee4", "\u1ee5", "\u1ee6", "\u1ee7", "\u1ee8", "\u1ee9", "\u1eea", "\u1eeb", "\u1eec", "\u1eed",
 1271+ "\u1eee", "\u1eef", "\u1ef0", "\u1ef1", "\u1e7c", "\u1e7d", "\u1e7e", "\u1e7f", "\u1efc", "\u1efd",
 1272+ "\u1e80", "\u1e81", "\u1e82", "\u1e83", "\u1e84", "\u1e85", "\u1e86", "\u1e87", "\u1e88", "\u1e89",
 1273+ "\u1e98", "\u1e8a", "\u1e8b", "\u1e8c", "\u1e8d", "\u1e8e", "\u1e8f", "\u1e99", "\u1ef2", "\u1ef3",
 1274+ "\u1ef4", "\u1ef5", "\u1ef6", "\u1ef7", "\u1ef8", "\u1ef9", "\u1efe", "\u1eff", "\u1e90", "\u1e91",
 1275+ "\u1e92", "\u1e93", "\u1e94", "\u1e95", "\u1e9e", "\u1e9f"
 1276+ ]
 1277+ },
 1278+ 'ipa': {
 1279+ labelMsg: 'wikieditor-toolbar-characters-page-ipa',
 1280+ layout: 'characters',
 1281+ characters: [
 1282+ "p", "t\u032a", "t", "\u0288", "c", "k", "q", "\u02a1", "\u0294", "b","d\u032a", "d", "\u0256",
 1283+ "\u025f", "\u0261", "\u0262", "\u0253", "\u0257", "\u0284", "\u0260", "\u029b", "t\u0361s",
 1284+ "t\u0361\u0283", "t\u0361\u0255", "d\u0361z", "d\u0361\u0292", "d\u0361\u0291", "\u0278", "f",
 1285+ "\u03b8", "s", "\u0283", "\u0285", "\u0286", "\u0282", "\u0255", "\u00e7", "\u0267", "x", "\u03c7",
 1286+ "\u0127", "\u029c", "h", "\u03b2", "v", "\u028d", "\u00f0", "z", "\u0292", "\u0293", "\u0290",
 1287+ "\u0291", "\u029d", "\u0263", "\u0281", "\u0295", "\u0296", "\u02a2", "\u0266", "\u026c", "\u026e",
 1288+ "m", "m\u0329", "\u0271", "\u0271\u0329", "\u0271\u030d", "n\u032a", "n\u032a\u030d", "n",
 1289+ "n\u0329", "\u0273", "\u0273\u0329", "\u0272", "\u0272\u0329", "\u014b", "\u014b\u030d",
 1290+ "\u014b\u0329", "\u0274", "\u0274\u0329", "\u0299", "\u0299\u0329", "r", "r\u0329", "\u0280",
 1291+ "\u0280\u0329", "\u027e", "\u027d", "\u027f", "\u027a", "l\u032a", "l\u032a\u0329", "l", "l\u0329",
 1292+ "\u026b", "\u026b\u0329", "\u026d", "\u026d\u0329", "\u028e", "\u028e\u0329", "\u029f",
 1293+ "\u029f\u0329", "w", "\u0265", "\u028b", "\u0279", "\u027b", "j", "\u0270", "\u0298", "\u01c2",
 1294+ "\u01c0", "!", "\u01c1", "\u02b0", "\u02b1", "\u02b7", "\u02b8", "\u02b2", "\u02b3", "\u207f",
 1295+ "\u02e1", "\u02b4", "\u02b5", "\u02e2", "\u02e3", "\u02e0", "\u02b6", "\u02e4", "\u02c1", "\u02c0",
 1296+ "\u02bc", "i", "i\u032f", "\u0129", "y", "y\u032f", "\u1ef9", "\u026a", "\u026a\u032f",
 1297+ "\u026a\u0303", "\u028f", "\u028f\u032f", "\u028f\u0303", "\u0268", "\u0268\u032f", "\u0268\u0303",
 1298+ "\u0289", "\u0289\u032f", "\u0289\u0303", "\u026f", "\u026f\u032f", "\u026f\u0303", "u", "u\u032f",
 1299+ "\u0169", "\u028a", "\u028a\u032f", "\u028a\u0303", "e", "e\u032f", "\u1ebd", "\u00f8",
 1300+ "\u00f8\u032f", "\u00f8\u0303", "\u0258", "\u0258\u032f", "\u0258\u0303", "\u0275", "\u0275\u032f",
 1301+ "\u0275\u0303", "\u0264", "\u0264\u032f", "\u0264\u0303", "o", "o\u032f", "\u00f5", "\u025b",
 1302+ "\u025b\u032f", "\u025b\u0303", "\u0153", "\u0153\u032f", "\u0153\u0303", "\u025c", "\u025c\u032f",
 1303+ "\u025c\u0303", "\u0259", "\u0259\u032f", "\u0259\u0303", "\u025e", "\u025e\u032f", "\u025e\u0303",
 1304+ "\u028c", "\u028c\u032f", "\u028c\u0303", "\u0254", "\u0254\u032f", "\u0254\u0303", "\u00e6",
 1305+ "\u00e6\u032f", "\u00e6\u0303", "\u0276", "\u0276\u032f", "\u0276\u0303", "a", "a\u032f", "\u00e3",
 1306+ "\u0250", "\u0250\u032f", "\u0250\u0303", "\u0251", "\u0251\u032f", "\u0251\u0303", "\u0252",
 1307+ "\u0252\u032f", "\u0252\u0303", "\u02c8", "\u02cc", "\u02d0", "\u02d1", "\u02d8", ".", "\u203f",
 1308+ "|", "\u2016"
 1309+ ]
 1310+ },
 1311+ 'symbols': {
 1312+ 'labelMsg': 'wikieditor-toolbar-characters-page-symbols',
 1313+ 'layout': 'characters',
 1314+ 'characters': [
 1315+ "~", "|", "\u00a1", "\u00bf", "\u2020", "\u2021", "\u2194", "\u2191", "\u2193", "\u2022", "\u00b6",
 1316+ "#", "\u00bd", "\u2153", "\u2154", "\u00bc", "\u00be", "\u215b", "\u215c", "\u215d", "\u215e",
 1317+ "\u221e", "\u2018", "\u201e", "\u201c", "\u2019", "\u201d",
 1318+ {
 1319+ 'label': "\u00ab\u00bb",
 1320+ 'action': {
 1321+ 'type': 'encapsulate', 'options': { 'pre': "\u00ab", 'post': "\u00bb" }
 1322+ }
 1323+ },
 1324+ "\u00a4", "\u20b3", "\u0e3f", "\u20b5", "\u00a2", "\u20a1", "\u20a2", "$", "\u20ab", "\u20af",
 1325+ "\u20ac", "\u20a0", "\u20a3", "\u0192", "\u20b4", "\u20ad", "\u20a4", "\u2133", "\u20a5", "\u20a6",
 1326+ "\u2116", "\u20a7", "\u20b0", "\u00a3", "\u17db", "\u20a8", "\u20aa", "\u09f3", "\u20ae", "\u20a9",
 1327+ "\u00a5", "\u2660", "\u2663", "\u2665", "\u2666", "m\u00b2", "m\u00b3", "\u2013", "\u2014",
 1328+ "\u2026", "\u2018", "\u201c", "\u2019", "\u201d", "\u00b0", "\u2033", "\u2032", "\u2248", "\u2260",
 1329+ "\u2264", "\u2265", "\u00b1", "\u2212", "\u00d7", "\u00f7", "\u2190", "\u2192", "\u00b7", "\u00a7"
 1330+ ]
 1331+ },
 1332+ 'greek': {
 1333+ 'labelMsg': 'wikieditor-toolbar-characters-page-greek',
 1334+ 'layout': 'characters',
 1335+ 'language': 'hl',
 1336+ 'characters': [
 1337+ "\u0391", "\u0386", "\u03b1", "\u03ac", "\u0392", "\u03b2", "\u0393", "\u03b3", "\u0394", "\u03b4",
 1338+ "\u0395", "\u0388", "\u03b5", "\u03ad", "\u0396", "\u03b6", "\u0397", "\u0389", "\u03b7", "\u03ae",
 1339+ "\u0398", "\u03b8", "\u0399", "\u038a", "\u03b9", "\u03af", "\u039a", "\u03ba", "\u039b", "\u03bb",
 1340+ "\u039c", "\u03bc", "\u039d", "\u03bd", "\u039e", "\u03be", "\u039f", "\u038c", "\u03bf", "\u03cc",
 1341+ "\u03a0", "\u03c0", "\u03a1", "\u03c1", "\u03a3", "\u03c3", "\u03c2", "\u03a4", "\u03c4", "\u03a5",
 1342+ "\u038e", "\u03c5", "\u03cd", "\u03a6", "\u03c6", "\u03a7", "\u03c7", "\u03a8", "\u03c8", "\u03a9",
 1343+ "\u038f", "\u03c9", "\u03ce"
 1344+ ]
 1345+ },
 1346+ 'cyrillic': {
 1347+ 'labelMsg': 'wikieditor-toolbar-characters-page-cyrillic',
 1348+ 'layout': 'characters',
 1349+ 'characters': [
 1350+ "\u0410", "\u0430", "\u04d8", "\u04d9", "\u0411", "\u0431", "\u0412", "\u0432", "\u0413", "\u0433",
 1351+ "\u0490", "\u0491", "\u0403", "\u0453", "\u0492", "\u0493", "\u0414", "\u0434", "\u0402", "\u0452",
 1352+ "\u0415", "\u0435", "\u0404", "\u0454", "\u0401", "\u0451", "\u0416", "\u0436", "\u0417", "\u0437",
 1353+ "\u0405", "\u0455", "\u0418", "\u0438", "\u0406", "\u0456", "\u0407", "\u0457", "\u0130", "\u0419",
 1354+ "\u0439", "\u04e2", "\u04e3", "\u0408", "\u0458", "\u041a", "\u043a", "\u040c", "\u045c", "\u049a",
 1355+ "\u049b", "\u041b", "\u043b", "\u0409", "\u0459", "\u041c", "\u043c", "\u041d", "\u043d", "\u040a",
 1356+ "\u045a", "\u04a2", "\u04a3", "\u041e", "\u043e", "\u04e8", "\u04e9", "\u041f", "\u043f", "\u0420",
 1357+ "\u0440", "\u0421", "\u0441", "\u0422", "\u0442", "\u040b", "\u045b", "\u0423", "\u0443", "\u040e",
 1358+ "\u045e", "\u04ee", "\u04ef", "\u04b0", "\u04b1", "\u04ae", "\u04af", "\u0424", "\u0444", "\u0425",
 1359+ "\u0445", "\u04b2", "\u04b3", "\u04ba", "\u04bb", "\u0426", "\u0446", "\u0427", "\u0447", "\u04b6",
 1360+ "\u04b7", "\u040f", "\u045f", "\u0428", "\u0448", "\u0429", "\u0449", "\u042a", "\u044a", "\u042b",
 1361+ "\u044b", "\u042c", "\u044c", "\u042d", "\u044d", "\u042e", "\u044e", "\u042f", "\u044f"
 1362+ ]
 1363+ },
 1364+ 'arabic': {
 1365+ 'labelMsg': 'wikieditor-toolbar-characters-page-arabic',
 1366+ 'layout': 'characters',
 1367+ 'language': 'ar',
 1368+ 'direction': 'rtl',
 1369+ 'characters': [
 1370+ "\u061b", "\u061f", "\u0621", "\u0622", "\u0623", "\u0624", "\u0625", "\u0626", "\u0627", "\u0628",
 1371+ "\u0629", "\u062a", "\u062b", "\u062c", "\u062d", "\u062e", "\u062f", "\u0630", "\u0631", "\u0632",
 1372+ "\u0633", "\u0634", "\u0635", "\u0636", "\u0637", "\u0638", "\u0639", "\u063a", "\u0641", "\u0642",
 1373+ "\u0643", "\u0644", "\u0645", "\u0646", "\u0647", "\u0648", "\u0649", "\u064a", "\u060c", "\u067e",
 1374+ "\u0686", "\u0698", "\u06af", "\u06ad"
 1375+ ]
 1376+ },
 1377+ 'hebrew': {
 1378+ 'labelMsg': 'wikieditor-toolbar-characters-page-hebrew',
 1379+ 'layout': 'characters',
 1380+ 'direction': 'rtl',
 1381+ 'characters': [
 1382+ "\u05d0", "\u05d1", "\u05d2", "\u05d3", "\u05d4", "\u05d5", "\u05d6", "\u05d7", "\u05d8", "\u05d9",
 1383+ "\u05db", "\u05da", "\u05dc", "\u05de", "\u05dd", "\u05e0", "\u05df", "\u05e1", "\u05e2", "\u05e4",
 1384+ "\u05e3", "\u05e6", "\u05e5", "\u05e7", "\u05e8", "\u05e9", "\u05ea", "\u05f3", "\u05f4", "\u05f0",
 1385+ "\u05f1", "\u05f2", "\u05d0", "\u05d3", "\u05d4", "\u05d5", "\u05d6", "\u05d7", "\u05d8", "\u05d9",
 1386+ "\u05da", "\u05db", "\u05dc", "\u05dd", "\u05de", "\u05df", "\u05e0", "\u05e1", "\u05e2", "\u05e3",
 1387+ "\u05e4", "\u05be", "\u05f3", "\u05f4",
 1388+ [ "\u05b0\u25cc", "\u05b0" ], [ "\u05b1\u25cc", "\u05b1" ], [ "\u05b2\u25cc", "\u05b2" ],
 1389+ [ "\u05b3\u25cc", "\u05b3" ], [ "\u05b4\u25cc", "\u05b4" ], [ "\u05b5\u25cc", "\u05b5" ],
 1390+ [ "\u05b6\u25cc", "\u05b6" ], [ "\u05b7\u25cc", "\u05b7" ], [ "\u05b8\u25cc", "\u05b8" ],
 1391+ [ "\u05b9\u25cc", "\u05b9" ], [ "\u05bb\u25cc", "\u05bb" ], [ "\u05bc\u25cc", "\u05bc" ],
 1392+ [ "\u05c1\u25cc", "\u05c1" ], [ "\u05c2\u25cc", "\u05c2" ], [ "\u05c7\u25cc", "\u05c7" ],
 1393+ [ "\u0591\u25cc", "\u0591" ], [ "\u0592\u25cc", "\u0592" ], [ "\u0593\u25cc", "\u0593" ],
 1394+ [ "\u0594\u25cc", "\u0594" ], [ "\u0595\u25cc", "\u0595" ], [ "\u0596\u25cc", "\u0596" ],
 1395+ [ "\u0597\u25cc", "\u0597" ], [ "\u0598\u25cc", "\u0598" ], [ "\u0599\u25cc", "\u0599" ],
 1396+ [ "\u059a\u25cc", "\u059a" ], [ "\u059b\u25cc", "\u059b" ], [ "\u059c\u25cc", "\u059c" ],
 1397+ [ "\u059d\u25cc", "\u059d" ], [ "\u059e\u25cc", "\u059e" ], [ "\u059f\u25cc", "\u059f" ],
 1398+ [ "\u05a0\u25cc", "\u05a0" ], [ "\u05a1\u25cc", "\u05a1" ], [ "\u05a2\u25cc", "\u05a2" ],
 1399+ [ "\u05a3\u25cc", "\u05a3" ], [ "\u05a4\u25cc", "\u05a4" ], [ "\u05a5\u25cc", "\u05a5" ],
 1400+ [ "\u05a6\u25cc", "\u05a6" ], [ "\u05a7\u25cc", "\u05a7" ], [ "\u05a8\u25cc", "\u05a8" ],
 1401+ [ "\u05a9\u25cc", "\u05a9" ], [ "\u05aa\u25cc", "\u05aa" ], [ "\u05ab\u25cc", "\u05ab" ],
 1402+ [ "\u05ac\u25cc", "\u05ac" ], [ "\u05ad\u25cc", "\u05ad" ], [ "\u05ae\u25cc", "\u05ae" ],
 1403+ [ "\u05af\u25cc", "\u05af" ], [ "\u05bf\u25cc", "\u05bf" ], [ "\u05c0\u25cc", "\u05c0" ],
 1404+ [ "\u05c3\u25cc", "\u05c3" ]
 1405+ ]
 1406+ },
 1407+ 'bangla': {
 1408+ 'labelMsg': 'wikieditor-toolbar-characters-page-bangla',
 1409+ 'language': 'bn',
 1410+ 'layout': 'characters',
 1411+ 'characters': [
 1412+ "\u0985", "\u0986", "\u0987", "\u0988", "\u0989", "\u098a", "\u098b", "\u098f", "\u0990", "\u0993",
 1413+ "\u0994", "\u09be", "\u09bf", "\u09c0", "\u09c1", "\u09c2", "\u09c3", "\u09c7", "\u09c8", "\u09cb",
 1414+ "\u09cc", "\u0995", "\u0996", "\u0997", "\u0998", "\u0999", "\u099a", "\u099b", "\u099c", "\u099d",
 1415+ "\u099e", "\u099f", "\u09a0", "\u09a1", "\u09a2", "\u09a3", "\u09a4", "\u09a5", "\u09a6", "\u09a7",
 1416+ "\u09a8", "\u09aa", "\u09ab", "\u09ac", "\u09ad", "\u09ae", "\u09af", "\u09b0", "\u09b2", "\u09b6",
 1417+ "\u09b7", "\u09b8", "\u09b9", "\u09a1\u09bc", "\u09a2\u09bc", "\u09af\u09bc", "\u09ce", "\u0982",
 1418+ "\u0983", "\u0981", "\u09cd", "\u09e7", "\u09e8", "\u09e9", "\u09ea", "\u09eb", "\u09ec", "\u09ed",
 1419+ "\u09ee", "\u09ef", "\u09e6"
 1420+ ]
 1421+ },
 1422+ 'telugu': {
 1423+ 'labelMsg': 'wikieditor-toolbar-characters-page-telugu',
 1424+ 'language': 'te',
 1425+ 'layout': 'characters',
 1426+ 'characters': [
 1427+ "\u0c01", "\u0c02", "\u0c03", "\u0c05", "\u0c06", "\u0c07", "\u0c08", "\u0c09", "\u0c0a", "\u0c0b",
 1428+ "\u0c60", "\u0c0c", "\u0c61", "\u0c0e", "\u0c0f", "\u0c10", "\u0c12", "\u0c13", "\u0c14", "\u0c15",
 1429+ "\u0c16", "\u0c17", "\u0c18", "\u0c19", "\u0c1a", "\u0c1b", "\u0c1c", "\u0c1d", "\u0c1e", "\u0c1f",
 1430+ "\u0c20", "\u0c21", "\u0c22", "\u0c23", "\u0c24", "\u0c25", "\u0c26", "\u0c27", "\u0c28", "\u0c2a",
 1431+ "\u0c2b", "\u0c2c", "\u0c2d", "\u0c2e", "\u0c2f", "\u0c30", "\u0c31", "\u0c32", "\u0c33", "\u0c35",
 1432+ "\u0c36", "\u0c37", "\u0c38", "\u0c39", "\u0c3e", "\u0c3f", "\u0c40", "\u0c41", "\u0c42", "\u0c43",
 1433+ "\u0c44", "\u0c46", "\u0c47", "\u0c48", "\u0c4a", "\u0c4b", "\u0c4c", "\u0c4d", "\u0c62", "\u0c63",
 1434+ "\u0c58", "\u0c59", "\u0c66", "\u0c67", "\u0c68", "\u0c69", "\u0c6a", "\u0c6b", "\u0c6c", "\u0c6d",
 1435+ "\u0c6e", "\u0c6f", "\u0c3d", "\u0c78", "\u0c79", "\u0c7a", "\u0c7b", "\u0c7c", "\u0c7d", "\u0c7e",
 1436+ "\u0c7f"
 1437+ ]
 1438+ },
 1439+ 'sinhala': {
 1440+ 'labelMsg': 'wikieditor-toolbar-characters-page-sinhala',
 1441+ 'language': 'si',
 1442+ 'layout': 'characters',
 1443+ 'characters': [
 1444+ "\u0d85", "\u0d86", "\u0d87", "\u0d88", "\u0d89", "\u0d8a", "\u0d8b", "\u0d8c", "\u0d8d", "\u0d8e",
 1445+ "\u0d8f", "\u0d90", "\u0d91", "\u0d92", "\u0d93", "\u0d94", "\u0d95", "\u0d96", "\u0d9a", "\u0d9b",
 1446+ "\u0d9c", "\u0d9d", "\u0d9e", "\u0d9f", "\u0da0", "\u0da1", "\u0da2", "\u0da3", "\u0da4", "\u0da5",
 1447+ "\u0da6", "\u0da7", "\u0da8", "\u0da9", "\u0daa", "\u0dab", "\u0dac", "\u0dad", "\u0dae", "\u0daf",
 1448+ "\u0db0", "\u0db1", "\u0db3", "\u0db4", "\u0db5", "\u0db6", "\u0db7", "\u0db8", "\u0db9", "\u0dba",
 1449+ "\u0dbb", "\u0dbd", "\u0dc0", "\u0dc1", "\u0dc2", "\u0dc3", "\u0dc4", "\u0dc5", "\u0dc6",
 1450+ [ "\u25cc\u0dcf", "\u0dcf" ], [ "\u25cc\u0dd0", "\u0dd0" ], [ "\u25cc\u0dd1", "\u0dd1" ],
 1451+ [ "\u25cc\u0dd2", "\u0dd2" ], [ "\u25cc\u0dd3", "\u0dd3" ], [ "\u25cc\u0dd4", "\u0dd4" ],
 1452+ [ "\u25cc\u0dd6", "\u0dd6" ], [ "\u25cc\u0dd8", "\u0dd8" ], [ "\u25cc\u0df2", "\u0df2" ],
 1453+ [ "\u25cc\u0ddf", "\u0ddf" ], [ "\u25cc\u0df3", "\u0df3" ], [ "\u25cc\u0dd9", "\u0dd9" ],
 1454+ [ "\u25cc\u0dda", "\u0dda" ], [ "\u25cc\u0ddc", "\u0ddc" ], [ "\u25cc\u0ddd", "\u0ddd" ],
 1455+ [ "\u25cc\u0dde", "\u0dde" ], [ "\u25cc\u0dca", "\u0dca" ]
 1456+ ]
 1457+ },
 1458+ 'gujarati': {
 1459+ 'labelMsg': 'wikieditor-toolbar-characters-page-gujarati',
 1460+ 'language': 'gu',
 1461+ 'layout': 'characters',
 1462+ 'characters': [
 1463+ "\u0ad0", "\u0a85", "\u0a86", "\u0a87", "\u0a88", "\u0a89", "\u0a8a", "\u0a8b", "\u0ae0", "\u0a8c",
 1464+ "\u0ae1", "\u0a8d", "\u0a8f", "\u0a90", "\u0a91", "\u0a93", "\u0a94", "\u0a95", "\u0a96", "\u0a97",
 1465+ "\u0a98", "\u0a99", "\u0a9a", "\u0a9b", "\u0a9c", "\u0a9d", "\u0a9e", "\u0a9f", "\u0aa0", "\u0aa1",
 1466+ "\u0aa2", "\u0aa3", "\u0aa4", "\u0aa5", "\u0aa6", "\u0aa7", "\u0aa8", "\u0aaa", "\u0aab", "\u0aac",
 1467+ "\u0aad", "\u0aae", "\u0aaf", "\u0ab0", "\u0ab2", "\u0ab5", "\u0ab6", "\u0ab7", "\u0ab8", "\u0ab9",
 1468+ "\u0ab3", "\u0abd", [ "\u25cc\u0abe", "\u0abe" ], [ "\u25cc\u0abf", "\u0abf" ],
 1469+ [ "\u25cc\u0ac0", "\u0ac0" ], [ "\u25cc\u0ac1", "\u0ac1" ], [ "\u25cc\u0ac2", "\u0ac2" ],
 1470+ [ "\u25cc\u0ac3", "\u0ac3" ], [ "\u25cc\u0ac4", "\u0ac4" ], [ "\u25cc\u0ae2", "\u0ae2" ],
 1471+ [ "\u25cc\u0ae3", "\u0ae3" ], [ "\u25cc\u0ac5", "\u0ac5" ], [ "\u25cc\u0ac7", "\u0ac7" ],
 1472+ [ "\u25cc\u0ac8", "\u0ac8" ], [ "\u25cc\u0ac9", "\u0ac9" ], [ "\u25cc\u0acb", "\u0acb" ],
 1473+ [ "\u25cc\u0acc", "\u0acc" ], [ "\u25cc\u0acd", "\u0acd" ]
 1474+ ]
 1475+ }
 1476+ }
 1477+ },
 1478+ 'help': {
 1479+ labelMsg: 'wikieditor-toolbar-section-help',
 1480+ type: 'booklet',
 1481+ deferLoad: true,
 1482+ pages: {
 1483+ 'format': {
 1484+ labelMsg: 'wikieditor-toolbar-help-page-format',
 1485+ layout: 'table',
 1486+ headings: [
 1487+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1488+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1489+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1490+ ],
 1491+ rows: [
 1492+ {
 1493+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-italic-description' },
 1494+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-italic-syntax' },
 1495+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-italic-result' }
 1496+ },
 1497+ {
 1498+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-bold-description' },
 1499+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-bold-syntax' },
 1500+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-bold-result' }
 1501+ },
 1502+ {
 1503+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-bolditalic-description' },
 1504+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-bolditalic-syntax' },
 1505+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-bolditalic-result' }
 1506+ }
 1507+ ]
 1508+ },
 1509+ 'link': {
 1510+ labelMsg: 'wikieditor-toolbar-help-page-link',
 1511+ layout: 'table',
 1512+ headings: [
 1513+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1514+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1515+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1516+ ],
 1517+ rows: [
 1518+ {
 1519+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-ilink-description' },
 1520+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-ilink-syntax' },
 1521+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-ilink-result' }
 1522+ },
 1523+ {
 1524+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-xlink-description' },
 1525+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-xlink-syntax' },
 1526+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-xlink-result' }
 1527+ }
 1528+ ]
 1529+ },
 1530+ 'heading': {
 1531+ labelMsg: 'wikieditor-toolbar-help-page-heading',
 1532+ layout: 'table',
 1533+ headings: [
 1534+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1535+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1536+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1537+ ],
 1538+ rows: [
 1539+ {
 1540+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-heading1-description' },
 1541+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-heading1-syntax' },
 1542+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-heading1-result' }
 1543+ },
 1544+ {
 1545+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-heading2-description' },
 1546+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-heading2-syntax' },
 1547+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-heading2-result' }
 1548+ },
 1549+ {
 1550+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-heading3-description' },
 1551+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-heading3-syntax' },
 1552+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-heading3-result' }
 1553+ },
 1554+ {
 1555+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-heading4-description' },
 1556+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-heading4-syntax' },
 1557+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-heading4-result' }
 1558+ },
 1559+ {
 1560+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-heading5-description' },
 1561+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-heading5-syntax' },
 1562+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-heading5-result' }
 1563+ }
 1564+ ]
 1565+ },
 1566+ 'list': {
 1567+ labelMsg: 'wikieditor-toolbar-help-page-list',
 1568+ layout: 'table',
 1569+ headings: [
 1570+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1571+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1572+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1573+ ],
 1574+ rows: [
 1575+ {
 1576+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-ulist-description' },
 1577+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-ulist-syntax' },
 1578+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-ulist-result' }
 1579+ },
 1580+ {
 1581+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-olist-description' },
 1582+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-olist-syntax' },
 1583+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-olist-result' }
 1584+ }
 1585+ ]
 1586+ },
 1587+ 'file': {
 1588+ labelMsg: 'wikieditor-toolbar-help-page-file',
 1589+ layout: 'table',
 1590+ headings: [
 1591+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1592+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1593+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1594+ ],
 1595+ rows: [
 1596+ {
 1597+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-file-description' },
 1598+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-file-syntax' },
 1599+ 'result': { htmlMsg: [ 'wikieditor-toolbar-help-content-file-result', stylepath ] }
 1600+ }
 1601+ ]
 1602+ },
 1603+ 'reference': {
 1604+ labelMsg: 'wikieditor-toolbar-help-page-reference',
 1605+ layout: 'table',
 1606+ headings: [
 1607+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1608+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1609+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1610+ ],
 1611+ rows: [
 1612+ {
 1613+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-reference-description' },
 1614+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-reference-syntax' },
 1615+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-reference-result' }
 1616+ },
 1617+ {
 1618+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-rereference-description' },
 1619+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-rereference-syntax' },
 1620+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-rereference-result' }
 1621+ },
 1622+ {
 1623+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-showreferences-description' },
 1624+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-showreferences-syntax' },
 1625+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-showreferences-result' }
 1626+ }
 1627+ ]
 1628+ },
 1629+ 'discussion': {
 1630+ labelMsg: 'wikieditor-toolbar-help-page-discussion',
 1631+ layout: 'table',
 1632+ headings: [
 1633+ { textMsg: 'wikieditor-toolbar-help-heading-description' },
 1634+ { textMsg: 'wikieditor-toolbar-help-heading-syntax' },
 1635+ { textMsg: 'wikieditor-toolbar-help-heading-result' }
 1636+ ],
 1637+ rows: [
 1638+ {
 1639+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-signaturetimestamp-description' },
 1640+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-signaturetimestamp-syntax' },
 1641+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-signaturetimestamp-result' }
 1642+ },
 1643+ {
 1644+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-signature-description' },
 1645+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-signature-syntax' },
 1646+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-signature-result' }
 1647+ },
 1648+ {
 1649+ 'description': { htmlMsg: 'wikieditor-toolbar-help-content-indent-description' },
 1650+ 'syntax': { htmlMsg: 'wikieditor-toolbar-help-content-indent-syntax' },
 1651+ 'result': { htmlMsg: 'wikieditor-toolbar-help-content-indent-result' }
 1652+ }
 1653+ ]
 1654+ }
 1655+ }
 1656+ },
 1657+ 'dialogs': {
 1658+ 'insert-link': {
 1659+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 1660+ titleMsg: 'wikieditor-toolbar-tool-link-title',
 1661+ id: 'wikieditor-toolbar-link-dialog',
 1662+ html: '\
 1663+ <fieldset>\
 1664+ <div class="wikieditor-toolbar-field-wrapper">\
 1665+ <label for="wikieditor-toolbar-link-int-target" rel="wikieditor-toolbar-tool-link-int-target" id="wikieditor-toolbar-tool-link-int-target-label"></label>\
 1666+ <div id="wikieditor-toolbar-link-int-target-status"></div>\
 1667+ <input type="text" id="wikieditor-toolbar-link-int-target" />\
 1668+ </div>\
 1669+ <div class="wikieditor-toolbar-field-wrapper">\
 1670+ <label for="wikieditor-toolbar-link-int-text" rel="wikieditor-toolbar-tool-link-int-text"></label>\
 1671+ <input type="text" id="wikieditor-toolbar-link-int-text" />\
 1672+ </div>\
 1673+ <div class="wikieditor-toolbar-field-wrapper">\
 1674+ <div class="wikieditor-toolbar-floated-field-wrapper">\
 1675+ <input type="radio" id="wikieditor-toolbar-link-type-int" name="wikieditor-toolbar-link-type" selected />\
 1676+ <label for="wikieditor-toolbar-link-type-int" rel="wikieditor-toolbar-tool-link-int"></label>\
 1677+ </div>\
 1678+ <div class="wikieditor-toolbar-floated-field-wrapper">\
 1679+ <input type="radio" id="wikieditor-toolbar-link-type-ext" name="wikieditor-toolbar-link-type" />\
 1680+ <label for="wikieditor-toolbar-link-type-ext" rel="wikieditor-toolbar-tool-link-ext"></label>\
 1681+ </div>\
 1682+ </div>\
 1683+ </fieldset>',
 1684+ init: function() {
 1685+ function isExternalLink( s ) {
 1686+ // The following things are considered to be external links:
 1687+ // * Starts a URL protocol
 1688+ // * Starts with www.
 1689+ // All of these are potentially valid titles, and the latter two
 1690+ // categories match about 6300 titles in enwiki's ns0. Out of 6.9M
 1691+ // titles, that's 0.09%
 1692+ if ( typeof arguments.callee.regex == 'undefined' ) {
 1693+ // Cache the regex
 1694+ arguments.callee.regex =
 1695+ new RegExp( "^(" + wgUrlProtocols + "|www\\.)", 'i');
 1696+ }
 1697+ return s.match( arguments.callee.regex );
 1698+ }
 1699+ // Updates the status indicator above the target link
 1700+ function updateWidget( status ) {
 1701+ $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide();
 1702+ $j( '#wikieditor-toolbar-link-int-target' ).parent()
 1703+ .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' );
 1704+ if ( status ) {
 1705+ $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show();
 1706+ $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status );
 1707+ }
 1708+ if ( status == 'invalid' ) {
 1709+ $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
 1710+ .attr( 'disabled', true )
 1711+ .addClass( 'disabled' );
 1712+ } else {
 1713+ $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' )
 1714+ .removeAttr('disabled')
 1715+ .removeClass('disabled');
 1716+ }
 1717+ }
 1718+ // Updates the UI to show if the page title being inputed by the user exists or not
 1719+ // accepts parameter internal for bypassing external link detection
 1720+ function updateExistence( internal ) {
 1721+ // ensure the internal parameter is a boolean
 1722+ if ( internal != true ) internal = false;
 1723+ // Abort previous request
 1724+ var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
 1725+ if ( request ) {
 1726+ request.abort();
 1727+ }
 1728+ var target = $j( '#wikieditor-toolbar-link-int-target' ).val();
 1729+ var cache = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'existencecache' );
 1730+ if ( cache[target] ) {
 1731+ updateWidget( cache[target] );
 1732+ return;
 1733+ }
 1734+ if ( target.replace( /^\s+$/,'' ) == '' ) {
 1735+ // Hide the widget when the textbox is empty
 1736+ updateWidget( false );
 1737+ return;
 1738+ }
 1739+ // If the forced internal paremter was not true, check if the target is an external link
 1740+ if ( !internal && isExternalLink( target ) ) {
 1741+ updateWidget( 'external' );
 1742+ return;
 1743+ }
 1744+ if ( target.indexOf( '|' ) != -1 ) {
 1745+ // Title contains | , which means it's invalid
 1746+ // but confuses the API. Show invalid and bypass API
 1747+ updateWidget( 'invalid' );
 1748+ return;
 1749+ }
 1750+ // Show loading spinner while waiting for the API to respond
 1751+ updateWidget( 'loading' );
 1752+ // Call the API to check page status, saving the request object so it can be aborted if necessary
 1753+ $j( '#wikieditor-toolbar-link-int-target-status' ).data(
 1754+ 'request',
 1755+ $j.ajax( {
 1756+ url: wgScriptPath + '/api.php',
 1757+ dataType: 'json',
 1758+ data: {
 1759+ 'action': 'query',
 1760+ 'indexpageids': '',
 1761+ 'titles': target,
 1762+ 'format': 'json'
 1763+ },
 1764+ success: function( data ) {
 1765+ if ( !data ) {
 1766+ // This happens in some weird cases
 1767+ return;
 1768+ }
 1769+ var status;
 1770+ if ( typeof data.query == 'undefined' ) {
 1771+ status = 'invalid';
 1772+ } else {
 1773+ var page = data.query.pages[data.query.pageids[0]];
 1774+ status = 'exists';
 1775+ if ( typeof page.missing != 'undefined' )
 1776+ status = 'notexists';
 1777+ else if ( typeof page.invalid != 'undefined' )
 1778+ status = 'invalid';
 1779+ }
 1780+ // Cache the status of the link target if the force internal parameter was not passed
 1781+ if ( !internal ) cache[target] = status;
 1782+ updateWidget( status );
 1783+ }
 1784+ } )
 1785+ );
 1786+ }
 1787+ $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).click( function() {
 1788+ if( $j( '#wikieditor-toolbar-link-type-ext' ).is( ':checked' ) ) {
 1789+ // Abort previous request
 1790+ var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' );
 1791+ if ( request ) {
 1792+ request.abort();
 1793+ }
 1794+ updateWidget( 'external' );
 1795+ }
 1796+ if( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) )
 1797+ updateExistence( true );
 1798+ });
 1799+ // Set labels of tabs based on rel values
 1800+ var u = mw.usability;
 1801+ $j(this).find( '[rel]' ).each( function() {
 1802+ $j(this).text( u.getMsg( $j(this).attr( 'rel' ) ) );
 1803+ });
 1804+ // Set tabindexes on form fields
 1805+ $j.wikiEditor.modules.dialogs.fn.setTabindexes( $j(this).find( 'input' ).not( '[tabindex]' ) );
 1806+ // Setup the tooltips in the textboxes
 1807+ $j( '#wikieditor-toolbar-link-int-target' )
 1808+ .data( 'tooltip', u.getMsg( 'wikieditor-toolbar-tool-link-int-target-tooltip' ) );
 1809+ $j( '#wikieditor-toolbar-link-int-text' )
 1810+ .data( 'tooltip', u.getMsg( 'wikieditor-toolbar-tool-link-int-text-tooltip' ) );
 1811+ $j( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' )
 1812+ .each( function() {
 1813+ var tooltip = u.getMsg( $j( this ).attr( 'id' ) + '-tooltip' );
 1814+ if ( $j( this ).val() == '' )
 1815+ $j( this )
 1816+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 1817+ .val( $j( this ).data( 'tooltip' ) )
 1818+ .data( 'tooltip-mode', true );
 1819+ } )
 1820+ .focus( function() {
 1821+ if( $j( this ).val() == $j( this ).data( 'tooltip' ) ) {
 1822+ $j( this )
 1823+ .val( '' )
 1824+ .removeClass( 'wikieditor-toolbar-dialog-hint' )
 1825+ .data( 'tooltip-mode', false );
 1826+ }
 1827+ })
 1828+ .bind( 'change', function() {
 1829+ if ( $j( this ).val() != $j( this ).data( 'tooltip' ) ) {
 1830+ $j( this )
 1831+ .removeClass( 'wikieditor-toolbar-dialog-hint' )
 1832+ .data( 'tooltip-mode', false );
 1833+ }
 1834+ })
 1835+ .bind( 'blur', function() {
 1836+ if ( $j( this ).val() == '' ) {
 1837+ $j( this )
 1838+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 1839+ .val( $j( this ).data( 'tooltip' ) )
 1840+ .data( 'tooltip-mode', true );
 1841+ }
 1842+ });
 1843+
 1844+ // Automatically copy the value of the internal link page title field to the link text field unless the user
 1845+ // has changed the link text field - this is a convenience thing since most link texts are going to be the
 1846+ // the same as the page title
 1847+ // Also change the internal/external radio button accordingly
 1848+ $j( '#wikieditor-toolbar-link-int-target' ).bind( 'change keydown paste cut', function() {
 1849+ // $j(this).val() is the old value, before the keypress
 1850+ // Defer this until $j(this).val() has been updated
 1851+ setTimeout( function() {
 1852+ if ( isExternalLink( $j( '#wikieditor-toolbar-link-int-target' ).val() ) ) {
 1853+ $j( '#wikieditor-toolbar-link-type-ext' ).attr( 'checked', 'checked' );
 1854+ updateWidget( 'external' );
 1855+ } else {
 1856+ $j( '#wikieditor-toolbar-link-type-int' ).attr( 'checked', 'checked' );
 1857+ updateExistence();
 1858+ }
 1859+ if ( $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched' ) )
 1860+ if ( $j( '#wikieditor-toolbar-link-int-target' ).val() ==
 1861+ $j( '#wikieditor-toolbar-link-int-target' ).data( 'tooltip' ) ) {
 1862+ $j( '#wikieditor-toolbar-link-int-text' )
 1863+ .addClass( 'wikieditor-toolbar-dialog-hint' )
 1864+ .val( $j( '#wikieditor-toolbar-link-int-text' ).data( 'tooltip' ) )
 1865+ .change();
 1866+ } else {
 1867+ $j( '#wikieditor-toolbar-link-int-text' )
 1868+ .val( $j( '#wikieditor-toolbar-link-int-target' ).val() )
 1869+ .change();
 1870+ }
 1871+ }, 0 );
 1872+ });
 1873+ $j( '#wikieditor-toolbar-link-int-text' ).bind( 'change keydown paste cut', function() {
 1874+ var oldVal = $j(this).val();
 1875+ var that = this;
 1876+ setTimeout( function() {
 1877+ if ( $j(that).val() != oldVal )
 1878+ $j(that).data( 'untouched', false );
 1879+ }, 0 );
 1880+ });
 1881+ // Add images to the page existence widget, which will be shown mutually exclusively to communicate if the
 1882+ // page exists, does not exist or the title is invalid (like if it contains a | character)
 1883+ var existsMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-exists' );
 1884+ var notexistsMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-notexists' );
 1885+ var invalidMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-invalid' );
 1886+ var externalMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-external' );
 1887+ var loadingMsg = u.getMsg( 'wikieditor-toolbar-tool-link-int-target-status-loading' );
 1888+ $j( '#wikieditor-toolbar-link-int-target-status' )
 1889+ .append( $j( '<div />' )
 1890+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-exists' )
 1891+ .append( existsMsg )
 1892+ )
 1893+ .append( $j( '<div />' )
 1894+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-notexists' )
 1895+ .append( notexistsMsg )
 1896+ )
 1897+ .append( $j( '<div />' )
 1898+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-invalid' )
 1899+ .append( invalidMsg )
 1900+ )
 1901+ .append( $j( '<div />' )
 1902+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-external' )
 1903+ .append( externalMsg )
 1904+ )
 1905+ .append( $j( '<div />' )
 1906+ .attr( 'id', 'wikieditor-toolbar-link-int-target-status-loading' )
 1907+ .append( $j( '<img />' ).attr( {
 1908+ 'src': $j.wikiEditor.imgPath + 'dialogs/' + 'loading.gif',
 1909+ 'alt': loadingMsg,
 1910+ 'title': loadingMsg
 1911+ } ) )
 1912+ )
 1913+ .data( 'existencecache', {} )
 1914+ .children().hide();
 1915+
 1916+ $j( '#wikieditor-toolbar-link-int-target' )
 1917+ .bind( 'keyup paste cut', function() {
 1918+ // Cancel the running timer if applicable
 1919+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' ) {
 1920+ clearTimeout( $j(this).data( 'timerID' ) );
 1921+ }
 1922+ // Delay fetch for a while
 1923+ // FIXME: Make 120 configurable elsewhere
 1924+ var timerID = setTimeout( updateExistence, 120 );
 1925+ $j(this).data( 'timerID', timerID );
 1926+ } )
 1927+ .change( function() {
 1928+ // Cancel the running timer if applicable
 1929+ if ( typeof $j(this).data( 'timerID' ) != 'undefined' ) {
 1930+ clearTimeout( $j(this).data( 'timerID' ) );
 1931+ }
 1932+ // Fetch right now
 1933+ updateExistence();
 1934+ } );
 1935+
 1936+ // Title suggestions
 1937+ $j( '#wikieditor-toolbar-link-int-target' ).data( 'suggcache', {} ).suggestions( {
 1938+ fetch: function( query ) {
 1939+ var that = this;
 1940+ var title = $j(this).val();
 1941+
 1942+ if ( isExternalLink( title ) || title.indexOf( '|' ) != -1 || title == '') {
 1943+ $j(this).suggestions( 'suggestions', [] );
 1944+ return;
 1945+ }
 1946+
 1947+ var cache = $j(this).data( 'suggcache' );
 1948+ if ( typeof cache[title] != 'undefined' ) {
 1949+ $j(this).suggestions( 'suggestions', cache[title] );
 1950+ return;
 1951+ }
 1952+
 1953+ var request = $j.ajax( {
 1954+ url: wgScriptPath + '/api.php',
 1955+ data: {
 1956+ 'action': 'opensearch',
 1957+ 'search': title,
 1958+ 'namespace': 0,
 1959+ 'suggest': '',
 1960+ 'format': 'json'
 1961+ },
 1962+ dataType: 'json',
 1963+ success: function( data ) {
 1964+ cache[title] = data[1];
 1965+ $j(that).suggestions( 'suggestions', data[1] );
 1966+ }
 1967+ });
 1968+ $j(this).data( 'request', request );
 1969+ },
 1970+ cancel: function() {
 1971+ var request = $j(this).data( 'request' );
 1972+ if ( request )
 1973+ request.abort();
 1974+ }
 1975+ });
 1976+ },
 1977+ dialog: {
 1978+ width: 500,
 1979+ dialogClass: 'wikiEditor-toolbar-dialog',
 1980+ buttons: {
 1981+ 'wikieditor-toolbar-tool-link-insert': function() {
 1982+ function escapeInternalText( s ) {
 1983+ // FIXME: Should this escape [[ too? Seems to work without that
 1984+ return s.replace( /(]{2,})/g, '<nowiki>$1</nowiki>' );
 1985+ }
 1986+ function escapeExternalTarget( s ) {
 1987+ return s.replace( / /g, '%20' )
 1988+ .replace( /\[/g, '%5B' )
 1989+ .replace( /]/g, '%5D' );
 1990+ }
 1991+ function escapeExternalText( s ) {
 1992+ // FIXME: Should this escape [ too? Seems to work without that
 1993+ return s.replace( /(]+)/g, '<nowiki>$1</nowiki>' );
 1994+ }
 1995+ var insertText = '';
 1996+ var whitespace = $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace' );
 1997+ var target = $j( '#wikieditor-toolbar-link-int-target' ).val();
 1998+ var text = $j( '#wikieditor-toolbar-link-int-text' ).val();
 1999+ // check if the tooltips were passed as target or text
 2000+ if ( $j( '#wikieditor-toolbar-link-int-target' ).data( 'tooltip-mode' ) )
 2001+ target = "";
 2002+ if ( $j( '#wikieditor-toolbar-link-int-text' ).data( 'tooltip-mode' ) )
 2003+ text = "";
 2004+ var u = mw.usability;
 2005+ if ( target == '' ) {
 2006+ alert( u.getMsg( 'wikieditor-toolbar-tool-link-empty' ) );
 2007+ return;
 2008+ }
 2009+ if ( $j.trim( text ) == '' ) {
 2010+ // [[Foo| ]] creates an invisible link
 2011+ // Instead, generate [[Foo|]]
 2012+ text = '';
 2013+ }
 2014+ if ( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) ) {
 2015+ // FIXME: Exactly how fragile is this?
 2016+ if ( $j( '#wikieditor-toolbar-link-int-target-status-invalid' ).is( ':visible' ) ) {
 2017+ // Refuse to add links to invalid titles
 2018+ alert( u.getMsg( 'wikieditor-toolbar-tool-link-int-invalid' ) );
 2019+ return;
 2020+ }
 2021+
 2022+ if ( target == text || !text.length )
 2023+ insertText = '[[' + target + ']]';
 2024+ else
 2025+ insertText = '[[' + target + '|' + escapeInternalText( text ) + ']]';
 2026+ } else {
 2027+ // Prepend http:// if there is no protocol
 2028+ if ( !target.match( /^[a-z]+:\/\/./ ) )
 2029+ target = 'http://' + target;
 2030+
 2031+ // Detect if this is really an internal link in disguise
 2032+ var match = target.match( $j(this).data( 'articlePathRegex' ) );
 2033+ if ( match && !$j(this).data( 'ignoreLooksInternal' ) ) {
 2034+ var buttons = { };
 2035+ var that = this;
 2036+ buttons[ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal-int' ) ] = function() {
 2037+ $j( '#wikieditor-toolbar-link-int-target' ).val( match[1] ).change();
 2038+ $j(this).dialog( 'close' );
 2039+ };
 2040+ buttons[ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal-ext' ) ] = function() {
 2041+ $j(that).data( 'ignoreLooksInternal', true );
 2042+ $j(that).closest( '.ui-dialog' ).find( 'button:first' ).click();
 2043+ $j(that).data( 'ignoreLooksInternal', false );
 2044+ $j(this).dialog( 'close' );
 2045+ };
 2046+ $j.wikiEditor.modules.dialogs.quickDialog(
 2047+ u.getMsg( 'wikieditor-toolbar-tool-link-lookslikeinternal', match[1] ),
 2048+ { buttons: buttons }
 2049+ );
 2050+ return;
 2051+ }
 2052+
 2053+ var escTarget = escapeExternalTarget( target );
 2054+ var escText = escapeExternalText( text );
 2055+
 2056+ if ( escTarget == escText )
 2057+ insertText = escTarget;
 2058+ else if ( text == '' )
 2059+ insertText = '[' + escTarget + ']';
 2060+ else
 2061+ insertText = '[' + escTarget + ' ' + escText + ']';
 2062+ }
 2063+ // Preserve whitespace in selection when replacing
 2064+ if ( whitespace ) insertText = whitespace[0] + insertText + whitespace[1];
 2065+ $j(this).dialog( 'close' );
 2066+ $j.wikiEditor.modules.toolbar.fn.doAction( $j(this).data( 'context' ), {
 2067+ type: 'replace',
 2068+ options: {
 2069+ pre: insertText
 2070+ }
 2071+ }, $j(this) );
 2072+
 2073+ // Blank form
 2074+ $j( '#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text' ).val( '' );
 2075+ $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).attr( 'checked', '' );
 2076+ },
 2077+ 'wikieditor-toolbar-tool-link-cancel': function() {
 2078+ // Clear any saved selection state
 2079+ var context = $j(this).data( 'context' );
 2080+ context.fn.restoreStuffForIE();
 2081+ $j(this).dialog( 'close' );
 2082+ }
 2083+ },
 2084+ open: function() {
 2085+ // Cache the articlepath regex
 2086+ $j(this).data( 'articlePathRegex', new RegExp(
 2087+ '^' + RegExp.escape( wgServer + wgArticlePath )
 2088+ .replace( /\\\$1/g, '(.*)' ) + '$'
 2089+ ) );
 2090+ // Pre-fill the text fields based on the current selection
 2091+ var context = $j(this).data( 'context' );
 2092+ // Restore and immediately save selection state, needed for inserting stuff later
 2093+ context.fn.restoreStuffForIE();
 2094+ context.fn.saveStuffForIE();
 2095+ var selection = context.$textarea.textSelection( 'getSelection' );
 2096+ $j( '#wikieditor-toolbar-link-int-target' ).focus();
 2097+ // Trigger the change event, so the link status indicator is up to date
 2098+ $j( '#wikieditor-toolbar-link-int-target' ).change();
 2099+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ '', '' ] );
 2100+ if ( selection != '' ) {
 2101+ var target, text, type;
 2102+ var matches;
 2103+ if ( ( matches = selection.match( /^(\s*)\[\[([^\]\|]+)(\|([^\]\|]*))?\]\](\s*)$/ ) ) ) {
 2104+ // [[foo|bar]] or [[foo]]
 2105+ target = matches[2];
 2106+ text = ( matches[4] ? matches[4] : matches[2] );
 2107+ type = 'int';
 2108+ // Preserve whitespace when replacing
 2109+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[1], matches[5] ] );
 2110+ } else if ( ( matches = selection.match( /^(\s*)\[([^\] ]+)( ([^\]]+))?\](\s*)$/ ) ) ) {
 2111+ // [http://www.example.com foo] or [http://www.example.com]
 2112+ target = matches[2];
 2113+ text = ( matches[4] ? matches[4] : '' );
 2114+ type = 'ext';
 2115+ // Preserve whitespace when replacing
 2116+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [ matches[1], matches[5] ] );
 2117+ } else {
 2118+ // Trim any leading and trailing whitespace from the selection,
 2119+ // but preserve it when replacing
 2120+ target = text = $j.trim( selection );
 2121+ if ( target.length < selection.length ) {
 2122+ $j( '#wikieditor-toolbar-link-dialog' ).data( 'whitespace', [
 2123+ selection.substr( 0, selection.indexOf( target.charAt( 0 ) ) ),
 2124+ selection.substr(
 2125+ selection.lastIndexOf( target.charAt( target.length - 1 ) ) + 1
 2126+ ) ]
 2127+ );
 2128+ }
 2129+ }
 2130+
 2131+ // Change the value by calling val() doesn't trigger the change event, so let's do that ourselves
 2132+ if ( typeof text != 'undefined' )
 2133+ $j( '#wikieditor-toolbar-link-int-text' ).val( text ).change();
 2134+ if ( typeof target != 'undefined' )
 2135+ $j( '#wikieditor-toolbar-link-int-target' ).val( target ).change();
 2136+ if ( typeof type != 'undefined' )
 2137+ $j( '#wikieditor-toolbar-link-' + type ).attr( 'checked', 'checked' );
 2138+ }
 2139+ $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched',
 2140+ $j( '#wikieditor-toolbar-link-int-text' ).val() ==
 2141+ $j( '#wikieditor-toolbar-link-int-target' ).val() ||
 2142+ $j( '#wikieditor-toolbar-link-int-text' ).hasClass( 'wikieditor-toolbar-dialog-hint' )
 2143+ );
 2144+ $j( '#wikieditor-toolbar-link-int-target' ).suggestions();
 2145+
 2146+ //don't overwrite user's text
 2147+ if( selection != '' ){
 2148+ $j( '#wikieditor-toolbar-link-int-text' ).data( 'untouched', false );
 2149+ }
 2150+
 2151+ $j( '#wikieditor-toolbar-link-int-text, #wikiedit-toolbar-link-int-target' )
 2152+ .each( function() {
 2153+ if ( $j(this).val() == '' )
 2154+ $j(this).parent().find( 'label' ).show();
 2155+ });
 2156+
 2157+ if ( !( $j(this).data( 'dialogkeypressset' ) ) ) {
 2158+ $j(this).data( 'dialogkeypressset', true );
 2159+ // Execute the action associated with the first button
 2160+ // when the user presses Enter
 2161+ $j(this).closest( '.ui-dialog' ).keypress( function( e ) {
 2162+ if ( ( e.keyCode || e.which ) == 13 ) {
 2163+ var button = $j(this).data( 'dialogaction' ) || $j(this).find( 'button:first' );
 2164+ button.click();
 2165+ e.preventDefault();
 2166+ }
 2167+ });
 2168+
 2169+ // Make tabbing to a button and pressing
 2170+ // Enter do what people expect
 2171+ $j(this).closest( '.ui-dialog' ).find( 'button' ).focus( function() {
 2172+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', this );
 2173+ });
 2174+ }
 2175+ }
 2176+ }
 2177+ },
 2178+ 'insert-reference': {
 2179+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 2180+ titleMsg: 'wikieditor-toolbar-tool-reference-title',
 2181+ id: 'wikieditor-toolbar-reference-dialog',
 2182+ html: '\
 2183+ <div class="wikieditor-toolbar-dialog-wrapper">\
 2184+ <fieldset><div class="wikieditor-toolbar-table-form">\
 2185+ <div class="wikieditor-toolbar-field-wrapper">\
 2186+ <label for="wikieditor-toolbar-reference-text"\
 2187+ rel="wikieditor-toolbar-tool-reference-text"></label>\
 2188+ <input type="text" id="wikieditor-toolbar-reference-text" />\
 2189+ </div>\
 2190+ </div></fieldset>\
 2191+ </div>',
 2192+ init: function() {
 2193+ // Insert translated strings into labels
 2194+ $j( this ).find( '[rel]' ).each( function() {
 2195+ $j( this ).text( mw.usability.getMsg( $j( this ).attr( 'rel' ) ) );
 2196+ } );
 2197+
 2198+ },
 2199+ dialog: {
 2200+ dialogClass: 'wikiEditor-toolbar-dialog',
 2201+ width: 590,
 2202+ buttons: {
 2203+ 'wikieditor-toolbar-tool-reference-insert': function() {
 2204+ var insertText = $j( '#wikieditor-toolbar-reference-text' ).val();
 2205+ var whitespace = $j( '#wikieditor-toolbar-reference-dialog' ).data( 'whitespace' );
 2206+ var attributes = $j( '#wikieditor-toolbar-reference-dialog' ).data( 'attributes' );
 2207+ // Close the dialog
 2208+ $j( this ).dialog( 'close' );
 2209+ $j.wikiEditor.modules.toolbar.fn.doAction(
 2210+ $j( this ).data( 'context' ),
 2211+ {
 2212+ type: 'replace',
 2213+ options: {
 2214+ pre: whitespace[0] + '<ref' + attributes + '>',
 2215+ peri: insertText,
 2216+ post: '</ref>' + whitespace[1]
 2217+ }
 2218+ },
 2219+ $j( this )
 2220+ );
 2221+ // Restore form state
 2222+ $j( '#wikieditor-toolbar-reference-text' ).val( "" );
 2223+ },
 2224+ 'wikieditor-toolbar-tool-reference-cancel': function() {
 2225+ // Clear any saved selection state
 2226+ var context = $j( this ).data( 'context' );
 2227+ context.fn.restoreStuffForIE();
 2228+ $j( this ).dialog( 'close' );
 2229+ }
 2230+ },
 2231+ open: function() {
 2232+ // Pre-fill the text fields based on the current selection
 2233+ var context = $j(this).data( 'context' );
 2234+ // Restore and immediately save selection state, needed for inserting stuff later
 2235+ context.fn.restoreStuffForIE();
 2236+ context.fn.saveStuffForIE();
 2237+ var selection = context.$textarea.textSelection( 'getSelection' );
 2238+ // set focus
 2239+ $j( '#wikieditor-toolbar-reference-text' ).focus();
 2240+ $j( '#wikieditor-toolbar-reference-dialog' )
 2241+ .data( 'whitespace', [ '', '' ] )
 2242+ .data( 'attributes', '' );
 2243+ if ( selection != '' ) {
 2244+ var matches, text;
 2245+ if ( ( matches = selection.match( /^(\s*)<ref([^\>]*)>([^\<]*)<\/ref\>(\s*)$/ ) ) ) {
 2246+ text = matches[3];
 2247+ // Preserve whitespace when replacing
 2248+ $j( '#wikieditor-toolbar-reference-dialog' ).data( 'whitespace', [ matches[1], matches[4] ] );
 2249+ $j( '#wikieditor-toolbar-reference-dialog' ).data( 'attributes', matches[2] );
 2250+ } else {
 2251+ text = selection;
 2252+ }
 2253+ $j( '#wikieditor-toolbar-reference-text' ).val( text );
 2254+ }
 2255+ if ( !( $j( this ).data( 'dialogkeypressset' ) ) ) {
 2256+ $j( this ).data( 'dialogkeypressset', true );
 2257+ // Execute the action associated with the first button
 2258+ // when the user presses Enter
 2259+ $j( this ).closest( '.ui-dialog' ).keypress( function( e ) {
 2260+ if ( ( e.keyCode || e.which ) == 13 ) {
 2261+ var button = $j( this ).data( 'dialogaction' ) || $j( this ).find( 'button:first' );
 2262+ button.click();
 2263+ e.preventDefault();
 2264+ }
 2265+ } );
 2266+ // Make tabbing to a button and pressing
 2267+ // Enter do what people expect
 2268+ $j( this ).closest( '.ui-dialog' ).find( 'button' ).focus( function() {
 2269+ $j( this ).closest( '.ui-dialog' ).data( 'dialogaction', this );
 2270+ } );
 2271+ }
 2272+ }
 2273+ }
 2274+ },
 2275+ 'insert-table': {
 2276+ // For now, apply the old browser and iframe requirements to the link and table dialogs as well
 2277+ // This'll be removed once these dialogs are confirmed stable without the iframe and/or in more browsers
 2278+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 2279+ titleMsg: 'wikieditor-toolbar-tool-table-title',
 2280+ id: 'wikieditor-toolbar-table-dialog',
 2281+ // FIXME: Localize 'x'?
 2282+ html: '\
 2283+ <div class="wikieditor-toolbar-dialog-wrapper">\
 2284+ <fieldset><div class="wikieditor-toolbar-table-form">\
 2285+ <div class="wikieditor-toolbar-field-wrapper">\
 2286+ <input type="checkbox" id="wikieditor-toolbar-table-dimensions-header" checked />\
 2287+ <label for="wikieditor-toolbar-table-dimensions-header"\
 2288+ rel="wikieditor-toolbar-tool-table-dimensions-header"></label>\
 2289+ </div>\
 2290+ <div class="wikieditor-toolbar-field-wrapper">\
 2291+ <input type="checkbox" id="wikieditor-toolbar-table-wikitable" checked />\
 2292+ <label for="wikieditor-toolbar-table-wikitable" rel="wikieditor-toolbar-tool-table-wikitable"></label>\
 2293+ </div>\
 2294+ <div class="wikieditor-toolbar-field-wrapper">\
 2295+ <input type="checkbox" id="wikieditor-toolbar-table-sortable" />\
 2296+ <label for="wikieditor-toolbar-table-sortable" rel="wikieditor-toolbar-tool-table-sortable"></label>\
 2297+ </div>\
 2298+ <div class="wikieditor-toolbar-table-dimension-fields">\
 2299+ <div class="wikieditor-toolbar-field-wrapper">\
 2300+ <label for="wikieditor-toolbar-table-dimensions-rows"\
 2301+ rel="wikieditor-toolbar-tool-table-dimensions-rows"></label><br />\
 2302+ <input type="text" id="wikieditor-toolbar-table-dimensions-rows" size="4" />\
 2303+ </div>\
 2304+ <div class="wikieditor-toolbar-field-wrapper">\
 2305+ <label for="wikieditor-toolbar-table-dimensions-columns"\
 2306+ rel="wikieditor-toolbar-tool-table-dimensions-columns"></label><br />\
 2307+ <input type="text" id="wikieditor-toolbar-table-dimensions-columns" size="4" />\
 2308+ </div>\
 2309+ </div>\
 2310+ </div></fieldset>\
 2311+ <div class="wikieditor-toolbar-table-preview-wrapper" >\
 2312+ <span rel="wikieditor-toolbar-tool-table-example"></span>\
 2313+ <div class="wikieditor-toolbar-table-preview-content">\
 2314+ <table id="wikieditor-toolbar-table-preview" class="wikieditor-toolbar-table-preview wikitable">\
 2315+ <tr class="wikieditor-toolbar-table-preview-header">\
 2316+ <th rel="wikieditor-toolbar-tool-table-example-header"></th>\
 2317+ <th rel="wikieditor-toolbar-tool-table-example-header"></th>\
 2318+ <th rel="wikieditor-toolbar-tool-table-example-header"></th>\
 2319+ </tr><tr class="wikieditor-toolbar-table-preview-hidden" style="display: none;">\
 2320+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2321+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2322+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2323+ </tr><tr>\
 2324+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2325+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2326+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2327+ </tr><tr>\
 2328+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2329+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2330+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2331+ </tr><tr>\
 2332+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2333+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2334+ <td rel="wikieditor-toolbar-tool-table-example-cell-text"></td>\
 2335+ </tr>\
 2336+ </table>\
 2337+ </div>\
 2338+ </div></div>',
 2339+ init: function() {
 2340+ $j(this).find( '[rel]' ).each( function() {
 2341+ $j(this).text( mw.usability.getMsg( $j(this).attr( 'rel' ) ) );
 2342+ });
 2343+ // Set tabindexes on form fields
 2344+ $j.wikiEditor.modules.dialogs.fn.setTabindexes( $j(this).find( 'input' ).not( '[tabindex]' ) );
 2345+
 2346+ $j( '#wikieditor-toolbar-table-dimensions-rows' ).val( 3 );
 2347+ $j( '#wikieditor-toolbar-table-dimensions-columns' ).val( 3 );
 2348+ $j( '#wikieditor-toolbar-table-wikitable' ).click( function() {
 2349+ $j( '.wikieditor-toolbar-table-preview' ).toggleClass( 'wikitable' );
 2350+ });
 2351+
 2352+ // Hack for sortable preview: dynamically adding
 2353+ // sortable class doesn't work, so we use a clone
 2354+ // FIXME: Relies on sortable table internals
 2355+ $j( '#wikieditor-toolbar-table-preview' )
 2356+ .clone()
 2357+ .attr( 'id', 'wikieditor-toolbar-table-preview2' )
 2358+ .addClass( 'sortable' )
 2359+ .insertAfter( $j( '#wikieditor-toolbar-table-preview' ) )
 2360+ .hide();
 2361+ if ( typeof ts_makeSortable == 'function' )
 2362+ ts_makeSortable( $j( '#wikieditor-toolbar-table-preview2' ).get( 0 ) );
 2363+ $j( '#wikieditor-toolbar-table-sortable' ).click( function() {
 2364+ // Swap the currently shown one clone with the other one
 2365+ $j( '#wikieditor-toolbar-table-preview' )
 2366+ .hide()
 2367+ .attr( 'id', 'wikieditor-toolbar-table-preview3' );
 2368+ $j( '#wikieditor-toolbar-table-preview2' )
 2369+ .attr( 'id', 'wikieditor-toolbar-table-preview' )
 2370+ .show();
 2371+ $j( '#wikieditor-toolbar-table-preview3' ).attr( 'id', 'wikieditor-toolbar-table-preview2' );
 2372+ });
 2373+
 2374+ $j( '#wikieditor-toolbar-table-dimensions-header' ).click( function() {
 2375+ // Instead of show/hiding, switch the HTML around
 2376+ // We do this because the sortable tables script styles the first row,
 2377+ // visible or not
 2378+ var headerHTML = $j( '.wikieditor-toolbar-table-preview-header' ).html();
 2379+ var hiddenHTML = $j( '.wikieditor-toolbar-table-preview-hidden' ).html();
 2380+ $j( '.wikieditor-toolbar-table-preview-header' ).html( hiddenHTML );
 2381+ $j( '.wikieditor-toolbar-table-preview-hidden' ).html( headerHTML );
 2382+ if ( typeof ts_makeSortable == 'function' )
 2383+ ts_makeSortable(
 2384+ $j( '#wikieditor-toolbar-table-preview, #wikieditor-toolbar-table-preview2' )
 2385+ .filter( '.sortable' )
 2386+ .get( 0 )
 2387+ );
 2388+ });
 2389+
 2390+ },
 2391+ dialog: {
 2392+ resizable: false,
 2393+ dialogClass: 'wikiEditor-toolbar-dialog',
 2394+ width: 590,
 2395+ buttons: {
 2396+ 'wikieditor-toolbar-tool-table-insert': function() {
 2397+ var rowsVal = $j( '#wikieditor-toolbar-table-dimensions-rows' ).val();
 2398+ var colsVal = $j( '#wikieditor-toolbar-table-dimensions-columns' ).val();
 2399+ var rows = parseInt( rowsVal, 10 );
 2400+ var cols = parseInt( colsVal, 10 );
 2401+ var header = $j( '#wikieditor-toolbar-table-dimensions-header' ).is( ':checked' ) ? 1 : 0;
 2402+ var u = mw.usability;
 2403+ if ( isNaN( rows ) || isNaN( cols ) || rows != rowsVal || cols != colsVal ) {
 2404+ alert( u.getMsg( 'wikieditor-toolbar-tool-table-invalidnumber' ) );
 2405+ return;
 2406+ }
 2407+ if ( rows + header == 0 || cols == 0 ) {
 2408+ alert( u.getMsg( 'wikieditor-toolbar-tool-table-zero' ) );
 2409+ return;
 2410+ }
 2411+ if ( rows * cols > 1000 ) {
 2412+ alert( u.getMsg( 'wikieditor-toolbar-tool-table-toomany', 1000 ) );
 2413+ return;
 2414+ }
 2415+ var headerText = u.getMsg( 'wikieditor-toolbar-tool-table-example-header' );
 2416+ var normalText = u.getMsg( 'wikieditor-toolbar-tool-table-example' );
 2417+ var table = "";
 2418+ for ( var r = 0; r < rows + header; r++ ) {
 2419+ table += "|-\n";
 2420+ for ( var c = 0; c < cols; c++ ) {
 2421+ var isHeader = ( header && r == 0 );
 2422+ var delim = isHeader ? '!' : '|';
 2423+ if ( c > 0 ) {
 2424+ delim += delim;
 2425+ }
 2426+ table += delim + ' ' + ( isHeader ? headerText : normalText ) + ' ';
 2427+ }
 2428+ // Replace trailing space by newline
 2429+ // table[table.length - 1] is read-only
 2430+ table = table.substr( 0, table.length - 1 ) + "\n";
 2431+ }
 2432+ var classes = [];
 2433+ if ( $j( '#wikieditor-toolbar-table-wikitable' ).is( ':checked' ) )
 2434+ classes.push( 'wikitable' );
 2435+ if ( $j( '#wikieditor-toolbar-table-sortable' ).is( ':checked' ) )
 2436+ classes.push( 'sortable' );
 2437+ var classStr = classes.length > 0 ? ' class="' + classes.join( ' ' ) + '"' : '';
 2438+ $j(this).dialog( 'close' );
 2439+ $j.wikiEditor.modules.toolbar.fn.doAction(
 2440+ $j(this).data( 'context' ),
 2441+ {
 2442+ type: 'replace',
 2443+ options: {
 2444+ pre: '{|' + classStr + "\n",
 2445+ peri: table,
 2446+ post: '|}',
 2447+ ownline: true
 2448+ }
 2449+ },
 2450+ $j(this)
 2451+ );
 2452+
 2453+ // Restore form state
 2454+ $j( '#wikieditor-toolbar-table-dimensions-rows' ).val( 3 );
 2455+ $j( '#wikieditor-toolbar-table-dimensions-columns' ).val( 3 );
 2456+ // Simulate clicks instead of setting values, so the according
 2457+ // actions are performed
 2458+ if ( !$j( '#wikieditor-toolbar-table-dimensions-header' ).is( ':checked' ) )
 2459+ $j( '#wikieditor-toolbar-table-dimensions-header' ).click();
 2460+ if ( !$j( '#wikieditor-toolbar-table-wikitable' ).is( ':checked' ) )
 2461+ $j( '#wikieditor-toolbar-table-wikitable' ).click();
 2462+ if ( $j( '#wikieditor-toolbar-table-sortable' ).is( ':checked' ) )
 2463+ $j( '#wikieditor-toolbar-table-sortable' ).click();
 2464+ },
 2465+ 'wikieditor-toolbar-tool-table-cancel': function() {
 2466+ $j(this).dialog( 'close' );
 2467+ }
 2468+ },
 2469+ open: function() {
 2470+ $j( '#wikieditor-toolbar-table-dimensions-rows' ).focus();
 2471+ if ( !( $j(this).data( 'dialogkeypressset' ) ) ) {
 2472+ $j(this).data( 'dialogkeypressset', true );
 2473+ // Execute the action associated with the first button
 2474+ // when the user presses Enter
 2475+ $j(this).closest( '.ui-dialog' ).keypress( function( e ) {
 2476+ if ( ( e.keyCode || e.which ) == 13 ) {
 2477+ var button = $j(this).data( 'dialogaction' ) || $j(this).find( 'button:first' );
 2478+ button.click();
 2479+ e.preventDefault();
 2480+ }
 2481+ });
 2482+
 2483+ // Make tabbing to a button and pressing
 2484+ // Enter do what people expect
 2485+ $j(this).closest( '.ui-dialog' ).find( 'button' ).focus( function() {
 2486+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', this );
 2487+ });
 2488+ }
 2489+ }
 2490+ }
 2491+ },
 2492+ 'search-and-replace': {
 2493+ 'browsers': {
 2494+ // Left-to-right languages
 2495+ 'ltr': {
 2496+ 'msie': false,
 2497+ 'firefox': [['>=', 2]],
 2498+ 'opera': false,
 2499+ 'safari': [['>=', 3]],
 2500+ 'chrome': [['>=', 3]]
 2501+ },
 2502+ // Right-to-left languages
 2503+ 'rtl': {
 2504+ 'msie': false,
 2505+ 'firefox': [['>=', 2]],
 2506+ 'opera': false,
 2507+ 'safari': [['>=', 3]],
 2508+ 'chrome': [['>=', 3]]
 2509+ }
 2510+ },
 2511+ filters: [ '#wpTextbox1.toolbar-dialogs' ],
 2512+ titleMsg: 'wikieditor-toolbar-tool-replace-title',
 2513+ id: 'wikieditor-toolbar-replace-dialog',
 2514+ html: '\
 2515+ <div id="wikieditor-toolbar-replace-message">\
 2516+ <div id="wikieditor-toolbar-replace-nomatch" rel="wikieditor-toolbar-tool-replace-nomatch"></div>\
 2517+ <div id="wikieditor-toolbar-replace-success"></div>\
 2518+ <div id="wikieditor-toolbar-replace-emptysearch" rel="wikieditor-toolbar-tool-replace-emptysearch"></div>\
 2519+ <div id="wikieditor-toolbar-replace-invalidregex"></div>\
 2520+ </div>\
 2521+ <fieldset>\
 2522+ <div class="wikieditor-toolbar-field-wrapper">\
 2523+ <label for="wikieditor-toolbar-replace-search" rel="wikieditor-toolbar-tool-replace-search"></label>\
 2524+ <input type="text" id="wikieditor-toolbar-replace-search" style="width: 100%;" />\
 2525+ </div>\
 2526+ <div class="wikieditor-toolbar-field-wrapper">\
 2527+ <label for="wikieditor-toolbar-replace-replace" rel="wikieditor-toolbar-tool-replace-replace"></label>\
 2528+ <input type="text" id="wikieditor-toolbar-replace-replace" style="width: 100%;" />\
 2529+ </div>\
 2530+ <div class="wikieditor-toolbar-field-wrapper">\
 2531+ <input type="checkbox" id="wikieditor-toolbar-replace-case" />\
 2532+ <label for="wikieditor-toolbar-replace-case" rel="wikieditor-toolbar-tool-replace-case"></label>\
 2533+ </div>\
 2534+ <div class="wikieditor-toolbar-field-wrapper">\
 2535+ <input type="checkbox" id="wikieditor-toolbar-replace-regex" />\
 2536+ <label for="wikieditor-toolbar-replace-regex" rel="wikieditor-toolbar-tool-replace-regex"></label>\
 2537+ </div>\
 2538+ </fieldset>',
 2539+ init: function() {
 2540+ var u = mw.usability;
 2541+ $j(this).find( '[rel]' ).each( function() {
 2542+ $j(this).text( u.getMsg( $j(this).attr( 'rel' ) ) );
 2543+ });
 2544+ // Set tabindexes on form fields
 2545+ $j.wikiEditor.modules.dialogs.fn.setTabindexes( $j(this).find( 'input' ).not( '[tabindex]' ) );
 2546+
 2547+ // TODO: Find a cleaner way to share this function
 2548+ $j(this).data( 'replaceCallback', function( mode ) {
 2549+ $j( '#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex' ).hide();
 2550+ var searchStr = $j( '#wikieditor-toolbar-replace-search' ).val();
 2551+ if ( searchStr == '' ) {
 2552+ $j( '#wikieditor-toolbar-replace-emptysearch' ).show();
 2553+ return;
 2554+ }
 2555+ var replaceStr = $j( '#wikieditor-toolbar-replace-replace' ).val();
 2556+ var flags = 'm';
 2557+ var matchCase = $j( '#wikieditor-toolbar-replace-case' ).is( ':checked' );
 2558+ var isRegex = $j( '#wikieditor-toolbar-replace-regex' ).is( ':checked' );
 2559+ if ( !matchCase ) {
 2560+ flags += 'i';
 2561+ }
 2562+ if ( mode == 'replaceAll' ) {
 2563+ flags += 'g';
 2564+ }
 2565+ if ( !isRegex ) {
 2566+ searchStr = RegExp.escape( searchStr );
 2567+ }
 2568+ try {
 2569+ var regex = new RegExp( searchStr, flags );
 2570+ } catch( e ) {
 2571+ $j( '#wikieditor-toolbar-replace-invalidregex' )
 2572+ .text( u.getMsg( 'wikieditor-toolbar-tool-replace-invalidregex',
 2573+ e.message ) )
 2574+ .show();
 2575+ return;
 2576+ }
 2577+ var $textarea = $j(this).data( 'context' ).$textarea;
 2578+ var text = $textarea.textSelection( 'getContents' );
 2579+ var match = false;
 2580+ var offset, s;
 2581+ if ( mode != 'replaceAll' ) {
 2582+ offset = $j(this).data( 'offset' );
 2583+ s = text.substr( offset );
 2584+ match = s.match( regex );
 2585+ }
 2586+ if ( !match ) {
 2587+ // Search hit BOTTOM, continuing at TOP
 2588+ offset = 0;
 2589+ s = text;
 2590+ match = s.match( regex );
 2591+ }
 2592+
 2593+ if ( !match ) {
 2594+ $j( '#wikieditor-toolbar-replace-nomatch' ).show();
 2595+ } else if ( mode == 'replaceAll' ) {
 2596+ // Instead of using repetitive .match() calls, we use one .match() call with /g
 2597+ // and indexOf() followed by substr() to find the offsets. This is actually
 2598+ // faster because our indexOf+substr loop is faster than a match loop, and the
 2599+ // /g match is so ridiculously fast that it's negligible.
 2600+ var index;
 2601+ for ( var i = 0; i < match.length; i++ ) {
 2602+ index = s.indexOf( match[i] );
 2603+ if ( index == -1 ) {
 2604+ // This shouldn't happen
 2605+ break;
 2606+ }
 2607+ s = s.substr( index + match[i].length );
 2608+
 2609+ var start = index + offset;
 2610+ var end = start + match[i].length;
 2611+ var newEnd = start + replaceStr.length;
 2612+ $textarea
 2613+ .textSelection( 'setSelection', { 'start': start, 'end': end } )
 2614+ .textSelection( 'encapsulateSelection', {
 2615+ 'peri': replaceStr,
 2616+ 'replace': true } )
 2617+ .textSelection( 'setSelection', { 'start': start, 'end': newEnd } );
 2618+ offset = newEnd;
 2619+ }
 2620+ $j( '#wikieditor-toolbar-replace-success' )
 2621+ .text( u.getMsg( 'wikieditor-toolbar-tool-replace-success', match.length ) )
 2622+ .show();
 2623+ $j(this).data( 'offset', 0 );
 2624+ } else {
 2625+ var start = match.index + offset;
 2626+ var end = start + match[0].length;
 2627+ var newEnd = start + replaceStr.length;
 2628+ var context = $j( this ).data( 'context' );
 2629+ $textarea.textSelection( 'setSelection', { 'start': start,
 2630+ 'end': end } );
 2631+ if ( mode == 'replace' ) {
 2632+ $textarea
 2633+ .textSelection( 'encapsulateSelection', {
 2634+ 'peri': replaceStr,
 2635+ 'replace': true } )
 2636+ .textSelection( 'setSelection', {
 2637+ 'start': start,
 2638+ 'end': newEnd } );
 2639+ }
 2640+ $textarea.textSelection( 'scrollToCaretPosition' );
 2641+ $textarea.textSelection( 'setSelection', { 'start': start,
 2642+ 'end': mode == 'replace' ? newEnd : end } );
 2643+ $j( this ).data( 'offset', mode == 'replace' ? newEnd : end );
 2644+ var textbox = typeof context.$iframe != 'undefined' ? context.$iframe[0].contentWindow : $textarea[0];
 2645+ textbox.focus();
 2646+ }
 2647+ });
 2648+ },
 2649+ dialog: {
 2650+ width: 500,
 2651+ dialogClass: 'wikiEditor-toolbar-dialog',
 2652+ buttons: {
 2653+ 'wikieditor-toolbar-tool-replace-button-findnext': function( e ) {
 2654+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', e.target );
 2655+ $j(this).data( 'replaceCallback' ).call( this, 'find' );
 2656+ },
 2657+ 'wikieditor-toolbar-tool-replace-button-replacenext': function( e ) {
 2658+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', e.target );
 2659+ $j(this).data( 'replaceCallback' ).call( this, 'replace' );
 2660+ },
 2661+ 'wikieditor-toolbar-tool-replace-button-replaceall': function( e ) {
 2662+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', e.target );
 2663+ $j(this).data( 'replaceCallback' ).call( this, 'replaceAll' );
 2664+ },
 2665+ 'wikieditor-toolbar-tool-replace-close': function() {
 2666+ $j(this).dialog( 'close' );
 2667+ }
 2668+ },
 2669+ open: function() {
 2670+ $j(this).data( 'offset', 0 );
 2671+ $j( '#wikieditor-toolbar-replace-search' ).focus();
 2672+ $j( '#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex' ).hide();
 2673+ if ( !( $j(this).data( 'onetimeonlystuff' ) ) ) {
 2674+ $j(this).data( 'onetimeonlystuff', true );
 2675+ // Execute the action associated with the first button
 2676+ // when the user presses Enter
 2677+ $j(this).closest( '.ui-dialog' ).keypress( function( e ) {
 2678+ if ( ( e.keyCode || e.which ) == 13 ) {
 2679+ var button = $j(this).data( 'dialogaction' ) || $j(this).find( 'button:first' );
 2680+ button.click();
 2681+ e.preventDefault();
 2682+ }
 2683+ });
 2684+ // Make tabbing to a button and pressing
 2685+ // Enter do what people expect
 2686+ $j(this).closest( '.ui-dialog' ).find( 'button' ).focus( function() {
 2687+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', this );
 2688+ });
 2689+ }
 2690+ var dialog = $j(this).closest( '.ui-dialog' );
 2691+ var that = this;
 2692+ var context = $j(this).data( 'context' );
 2693+ var textbox = typeof context.$iframe != 'undefined' ?
 2694+ context.$iframe[0].contentWindow.document : context.$textarea;
 2695+
 2696+ $j( textbox )
 2697+ .bind( 'keypress.srdialog', function( e ) {
 2698+ if ( ( e.keyCode || e.which ) == 13 ) {
 2699+ // Enter
 2700+ var button = dialog.data( 'dialogaction' ) || dialog.find( 'button:first' );
 2701+ button.click();
 2702+ e.preventDefault();
 2703+ } else if ( ( e.keyCode || e.which ) == 27 ) {
 2704+ // Escape
 2705+ $j(that).dialog( 'close' );
 2706+ }
 2707+ });
 2708+ },
 2709+ close: function() {
 2710+ var context = $j(this).data( 'context' );
 2711+ var textbox = typeof context.$iframe != 'undefined' ?
 2712+ context.$iframe[0].contentWindow.document : context.$textarea;
 2713+ $j( textbox ).unbind( 'keypress.srdialog' );
 2714+ $j(this).closest( '.ui-dialog' ).data( 'dialogaction', false );
 2715+ }
 2716+ }
 2717+ }
 2718+ }
 2719+};
 2720+*/
\ No newline at end of file

Follow-up revisions

RevisionCommit summaryAuthorDate
r68744Followup to r68742...used a $ instead of a . Now clicking on the reply link p...adam21:03, 29 June 2010

Status & tagging log