r92873 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r92872‎ | r92873 | r92874 >
Date:18:36, 22 July 2011
Author:demon
Status:ok
Tags:
Comment:
Back AjaxCategories out of REL1_18 branch
Modified paths:
  • /branches/REL1_18/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/REL1_18/phase3/includes/OutputPage.php (modified) (history)
  • /branches/REL1_18/phase3/languages/messages/MessagesEn.php (modified) (history)
  • /branches/REL1_18/phase3/maintenance/language/messages.inc (modified) (history)
  • /branches/REL1_18/phase3/resources/Resources.php (modified) (history)
  • /branches/REL1_18/phase3/resources/mediawiki.page/mediawiki.page.ajaxCategories.init.js (deleted) (history)
  • /branches/REL1_18/phase3/resources/mediawiki.page/mediawiki.page.ajaxCategories.js (deleted) (history)

Diff [purge]

Index: branches/REL1_18/phase3/maintenance/language/messages.inc
@@ -3459,31 +3459,6 @@
34603460 'unwatch' => array(
34613461 'confirm-unwatch-button',
34623462 ),
3463 - 'ajax-category' => array(
3464 - 'ajax-add-category',
3465 - 'ajax-remove-category',
3466 - 'ajax-edit-category',
3467 - 'ajax-add-category-submit',
3468 - 'ajax-confirm-ok',
3469 - 'ajax-confirm-title',
3470 - 'ajax-confirm-prompt',
3471 - 'ajax-confirm-save',
3472 - 'ajax-confirm-save-all',
3473 - 'ajax-cancel',
3474 - 'ajax-add-category-summary',
3475 - 'ajax-edit-category-summary',
3476 - 'ajax-remove-category-summary',
3477 - 'ajax-add-category-question',
3478 - 'ajax-edit-category-question',
3479 - 'ajax-remove-category-question',
3480 - 'ajax-confirm-actionsummary',
3481 - 'ajax-error-title',
3482 - 'ajax-error-dismiss',
3483 - 'ajax-remove-category-error',
3484 - 'ajax-edit-category-error',
3485 - 'ajax-category-already-present',
3486 - ),
3487 -
34883463 );
34893464
34903465 /** Comments for each block */
Index: branches/REL1_18/phase3/includes/OutputPage.php
@@ -2339,7 +2339,7 @@
23402340 */
23412341 private function addDefaultModules() {
23422342 global $wgIncludeLegacyJavaScript, $wgUseAjax,
2343 - $wgAjaxWatch, $wgEnableMWSuggest, $wgUseAJAXCategories;
 2343+ $wgAjaxWatch, $wgEnableMWSuggest;
23442344
23452345 // Add base resources
23462346 $this->addModules( array(
@@ -2370,16 +2370,6 @@
23712371 if ( $this->getUser()->getBoolOption( 'editsectiononrightclick' ) ) {
23722372 $this->addModules( 'mediawiki.action.view.rightClickEdit' );
23732373 }
2374 -
2375 - if ( $wgUseAJAXCategories ) {
2376 - global $wgAJAXCategoriesNamespaces;
2377 -
2378 - $title = $this->getTitle();
2379 -
2380 - if( empty( $wgAJAXCategoriesNamespaces ) || in_array( $title->getNamespace(), $wgAJAXCategoriesNamespaces ) ) {
2381 - $this->addModules( 'mediawiki.page.ajaxCategories.init' );
2382 - }
2383 - }
23842374 }
23852375
23862376 /**
Index: branches/REL1_18/phase3/includes/DefaultSettings.php
@@ -5513,19 +5513,6 @@
55145514 $wgDBtestpassword = '';
55155515
55165516 /**
5517 - * Whether or not to use the AJAX categories system.
5518 - */
5519 -$wgUseAJAXCategories = false;
5520 -
5521 -/**
5522 - * Only enable AJAXCategories on configured namespaces. Default is all.
5523 - *
5524 - * Example:
5525 - * $wgAJAXCategoriesNamespaces = array( NS_MAIN, NS_PROJECT );
5526 - */
5527 -$wgAJAXCategoriesNamespaces = array();
5528 -
5529 -/**
55305517 * For really cool vim folding this needs to be at the end:
55315518 * vim: foldmarker=@{,@} foldmethod=marker
55325519 * @}
Index: branches/REL1_18/phase3/languages/messages/MessagesEn.php
@@ -4585,32 +4585,4 @@
45864586 # SQLite database support
45874587 'sqlite-has-fts' => '$1 with full-text search support',
45884588 'sqlite-no-fts' => '$1 without full-text search support',
4589 -
4590 -# Add categories per AJAX
4591 -'ajax-add-category' => 'Add category',
4592 -'ajax-remove-category' => 'Remove category',
4593 -'ajax-edit-category' => 'Edit category',
4594 -'ajax-add-category-submit' => 'Add',
4595 -'ajax-confirm-ok' => 'OK',
4596 -'ajax-confirm-title' => 'Confirm action',
4597 -'ajax-confirm-prompt' => 'You can provide an edit summary below.
4598 -Click "Save" to save your edit.',
4599 -'ajax-confirm-save' => 'Save',
4600 -'ajax-confirm-save-all' => 'Save all changes',
4601 -'ajax-cancel' => 'Cancel edits',
4602 -'ajax-add-category-summary' => 'Add category "$1"',
4603 -'ajax-edit-category-summary' => 'Change category "$1" to "$2"',
4604 -'ajax-remove-category-summary' => 'Remove category "$1"',
4605 -'ajax-add-category-question' => 'Why do you want to add category "$1"?',
4606 -'ajax-edit-category-question' => 'Why do you want to change category "$1" to "$2"?',
4607 -'ajax-remove-category-question' => 'Why do you want to remove category "$1"?',
4608 -'ajax-confirm-actionsummary' => 'Action to take:',
4609 -'ajax-error-title' => 'Error',
4610 -'ajax-error-dismiss' => 'OK',
4611 -'ajax-remove-category-error' => 'It was not possible to remove this category.
4612 -This usually occurs when the category has been added to the page in a template.',
4613 -'ajax-edit-category-error' => 'It was not possible to edit this category.
4614 -This usually occurs when the category has been added to the page in a template.',
4615 -'ajax-category-already-present' => 'This page already belongs to the category $1',
4616 -
46174589 );
Index: branches/REL1_18/phase3/resources/Resources.php
@@ -487,45 +487,6 @@
488488 'jquery.ui.autocomplete',
489489 ),
490490 ),
491 - 'mediawiki.page.ajaxCategories' => array(
492 - 'scripts' => 'resources/mediawiki.page/mediawiki.page.ajaxCategories.js',
493 - 'styles' => 'resources/mediawiki.page/mediawiki.page.ajaxCategories.css',
494 - 'dependencies' => array(
495 - 'jquery.suggestions',
496 - 'jquery.ui.dialog',
497 - 'mediawiki.Title',
498 - ),
499 - 'messages' => array(
500 - 'ajax-add-category',
501 - 'ajax-remove-category',
502 - 'ajax-edit-category',
503 - 'ajax-add-category-submit',
504 - 'ajax-confirm-ok',
505 - 'ajax-confirm-prompt',
506 - 'ajax-confirm-title',
507 - 'ajax-confirm-save',
508 - 'ajax-confirm-save-all',
509 - 'ajax-cancel',
510 - 'ajax-add-category-summary',
511 - 'ajax-remove-category-summary',
512 - 'ajax-edit-category-summary',
513 - 'ajax-add-category-question',
514 - 'ajax-edit-category-question',
515 - 'ajax-remove-category-question',
516 - 'ajax-confirm-actionsummary',
517 - 'ajax-error-title',
518 - 'ajax-error-dismiss',
519 - 'ajax-remove-category-error',
520 - 'ajax-edit-category-error',
521 - 'ajax-category-already-present',
522 - ),
523 - ),
524 - 'mediawiki.page.ajaxCategories.init' => array(
525 - 'scripts' => 'resources/mediawiki.page/mediawiki.page.ajaxCategories.init.js',
526 - 'dependencies' => array(
527 - 'mediawiki.page.ajaxCategories',
528 - ),
529 - ),
530491 'mediawiki.libs.jpegmeta' => array(
531492 'scripts' => 'resources/mediawiki.libs/mediawiki.libs.jpegmeta.js',
532493 ),
Index: branches/REL1_18/phase3/resources/mediawiki.page/mediawiki.page.ajaxCategories.js
@@ -1,732 +0,0 @@
2 -// TODO
3 -//
4 -// * The edit summary should contain the added/removed category name too.
5 -// Something like: "Category:Foo added. Reason"
6 -// Requirement: Be able to get msg with lang option.
7 -// * Handle uneditable cats. Needs serverside changes!
8 -// * Handle normal redirects
9 -// * Enter to submit
10 -
11 -( function( $ ) {
12 -
13 - /* Local scope */
14 -
15 - var catNsId = mw.config.get( 'wgNamespaceIds' ).category,
16 -
17 - clean = function( s ) {
18 - if ( s !== undefined ) {
19 - return s.replace( /[\x00-\x1f\x23\x3c\x3e\x5b\x5d\x7b\x7c\x7d\x7f\s]+/g, '' );
20 - }
21 - },
22 -
23 - /**
24 - * Build URL for passed Category
25 - *
26 - * @param string category name.
27 - * @return string Valid URL
28 - */
29 - catLink = function( cat ) {
30 - return mw.util.wikiGetlink( new mw.Title( cat, catNsId ) );
31 - };
32 -
33 -mw.ajaxCategories = function( options ) {
34 - //Save scope in shortcut
35 - var aC = this;
36 -
37 - // TODO grab these out of option object.
38 -
39 - var catLinkWrapper = '<li/>';
40 - var $container = $( '.catlinks' );
41 - var $containerNormal = $( '#mw-normal-catlinks' );
42 -
43 - var categoryLinkSelector = '#mw-normal-catlinks li a:not(.icon)';
44 - var _request;
45 -
46 - var _saveAllButton;
47 - var _cancelAllButton;
48 - var _multiEdit = mw.util.inArray( mw.config.get( 'wgUserGroups' ), 'user' );
49 -
50 - /**
51 - * Helper function for $.fn.suggestion
52 - *
53 - * @param string Query string.
54 - */
55 - _fetchSuggestions = function( query ) {
56 - var _this = this;
57 - // ignore bad characters, they will be stripped out
58 - var catName = clean( $( this ).val() );
59 - var request = $.ajax( {
60 - url: mw.util.wikiScript( 'api' ),
61 - data: {
62 - 'action': 'query',
63 - 'list': 'allpages',
64 - 'apnamespace': catNsId,
65 - 'apprefix': catName,
66 - 'format': 'json'
67 - },
68 - dataType: 'json',
69 - success: function( data ) {
70 - // Process data.query.allpages into an array of titles
71 - var pages = data.query.allpages;
72 - var titleArr = [];
73 -
74 - $.each( pages, function( i, page ) {
75 - var title = page.title.split( ':', 2 )[1];
76 - titleArr.push( title );
77 - } );
78 -
79 - $( _this ).suggestions( 'suggestions', titleArr );
80 - }
81 - } );
82 - //TODO
83 - _request = request;
84 - };
85 -
86 - /**
87 - * Insert a newly added category into the DOM
88 - *
89 - * @param string category name.
90 - * @return jQuery object
91 - */
92 - _createCatDOM = function( cat ) {
93 - // User can implicitely state a sort key.
94 - // Remove before display
95 - cat = cat.replace(/\|.*/, '');
96 -
97 - // strip out bad characters
98 - cat = clean ( cat );
99 -
100 - if ( $.isEmpty( cat ) || aC.containsCat( cat ) ) {
101 - return;
102 - }
103 -
104 - var $catLinkWrapper = $( catLinkWrapper );
105 - var $anchor = $( '<a/>' ).append( cat );
106 - $catLinkWrapper.append( $anchor );
107 - $anchor.attr( { target: "_blank", href: catLink( cat ) } );
108 -
109 - _createCatButtons( $anchor.get(0) );
110 -
111 - return $anchor;
112 - };
113 -
114 - _makeSuggestionBox = function( prefill, callback, buttonVal ) {
115 - // Create add category prompt
116 - var promptContainer = $( '<div class="mw-addcategory-prompt"/>' );
117 - var promptTextbox = $( '<input type="text" size="45" class="mw-addcategory-input"/>' );
118 - if ( prefill !== '' ) {
119 - promptTextbox.val( prefill );
120 - }
121 - var addButton = $( '<input type="button" class="mw-addcategory-button"/>' );
122 - addButton.val( buttonVal );
123 -
124 - addButton.click( callback );
125 -
126 - promptTextbox.suggestions( {
127 - 'fetch':_fetchSuggestions,
128 - 'cancel': function() {
129 - var req = _request;
130 - // XMLHttpRequest.abort is unimplemented in IE6, also returns nonstandard value of "unknown" for typeof
131 - if ( req && ( typeof req.abort !== 'unknown' ) && ( typeof req.abort !== 'undefined' ) && req.abort ) {
132 - req.abort();
133 - }
134 - }
135 - } );
136 -
137 - promptTextbox.suggestions();
138 -
139 - promptContainer.append( promptTextbox );
140 - promptContainer.append( addButton );
141 -
142 - return promptContainer;
143 - };
144 -
145 - /**
146 - * Parse the DOM $container and build a list of
147 - * present categories
148 - *
149 - * @return array Array of all categories
150 - */
151 - _getCats = function() {
152 - return $container.find( categoryLinkSelector ).map( function() { return $.trim( $( this ).text() ); } );
153 - };
154 -
155 - /**
156 - * Check whether a passed category is present in the DOM
157 - *
158 - * @return boolean True for exists
159 - */
160 - this.containsCat = function( cat ) {
161 - return _getCats().filter( function() { return $.ucFirst(this) == $.ucFirst(cat); } ).length !== 0;
162 - };
163 -
164 - /**
165 - * This gets called by all action buttons
166 - * Displays a dialog to confirm the action
167 - * Afterwords do the actual edit
168 - *
169 - * @param function fn text-modifying function
170 - * @param string actionSummary Changes done
171 - * @param function fn doneFn callback after everything is done
172 - * @return boolean True for exists
173 - */
174 - _confirmEdit = function( fn, actionSummary, doneFn, $link, action ) {
175 - // Check whether to use multiEdit mode
176 - if ( _multiEdit && action != 'all' ) {
177 - // Stash away
178 - $link.data('stashIndex', _stash.fns.length );
179 - _stash.summaries.push( actionSummary );
180 - _stash.fns.push( fn );
181 -
182 -
183 - //TODO add Cancel button
184 - _saveAllButton.show();
185 - //_cancelAllButton.show();
186 -
187 - // This only does visual changes
188 - doneFn( true );
189 - return;
190 - }
191 - // Produce a confirmation dialog
192 - var dialog = $( '<div/>' );
193 -
194 - dialog.addClass( 'mw-ajax-confirm-dialog' );
195 - dialog.attr( 'title', mw.msg( 'ajax-confirm-title' ) );
196 -
197 - // Intro text.
198 - var confirmIntro = $( '<p/>' );
199 - confirmIntro.text( mw.msg( 'ajax-confirm-prompt' ) );
200 - dialog.append( confirmIntro );
201 -
202 - // Summary of the action to be taken
203 - var summaryHolder = $( '<p/>' );
204 - var summaryLabel = $( '<strong/>' );
205 - summaryLabel.text( mw.msg( 'ajax-confirm-actionsummary' ) + " " );
206 - summaryHolder.text( actionSummary );
207 - summaryHolder.prepend( summaryLabel );
208 - dialog.append( summaryHolder );
209 -
210 - // Reason textbox.
211 - var reasonBox = $( '<input type="text" size="45" />' );
212 - reasonBox.addClass( 'mw-ajax-confirm-reason' );
213 - dialog.append( reasonBox );
214 -
215 - // Submit button
216 - var submitButton = $( '<input type="button"/>' );
217 - submitButton.val( mw.msg( 'ajax-confirm-save' ) );
218 -
219 - var submitFunction = function() {
220 - _addProgressIndicator( dialog );
221 - _doEdit(
222 - mw.config.get( 'wgPageName' ),
223 - fn,
224 - reasonBox.val(),
225 - function() {
226 - doneFn();
227 - dialog.dialog( 'close' );
228 - _removeProgressIndicator( dialog );
229 - }
230 - );
231 - };
232 -
233 - var buttons = {};
234 - buttons[mw.msg( 'ajax-confirm-save' )] = submitFunction;
235 - var dialogOptions = {
236 - 'AutoOpen' : true,
237 - 'buttons' : buttons,
238 - 'width' : 450
239 - };
240 -
241 - $( '#catlinks' ).prepend( dialog );
242 - dialog.dialog( dialogOptions );
243 - };
244 -
245 - /**
246 - * When multiEdit mode is enabled,
247 - * this is called when the user clicks "save all"
248 - * Combines the summaries and edit functions
249 - */
250 - _handleStashedCategories = function() {
251 - // Save fns
252 - fns = _stash.fns;
253 -
254 - //TODO Add spaces in msg
255 - var summary = _stash.summaries.join();
256 - if ( summary == '' ) {
257 - _saveAllButton.hide();
258 - return;
259 - }
260 - var combinedFn = function( oldtext ) {
261 - // Run the text through all action functions
262 - newtext = oldtext;
263 - for ( var i = 0; i < fns.length; i++ ) {
264 - if ( $.isfunction( fns[i] ) ) {
265 - newtext = fns[i]( newtext );
266 - }
267 - }
268 - return newtext;
269 - };
270 - var doneFn = _resetToActual;
271 -
272 - _confirmEdit( combinedFn, summary, doneFn, '', 'all' );
273 - };
274 -
275 - _resetToActual = function() {
276 - //Remove saveAllButton
277 - _saveAllButton.hide();
278 - _cancelAllButton.hide();
279 -
280 - // Clean stash
281 - _stash.fns = [];
282 - _stash.summaries = [];
283 -
284 - // TODO
285 - $container.find('.mw-removed-category').parent().remove();
286 - // Any link with $link.css('text-decoration', 'line-through');
287 - // needs to be removed
288 -
289 - };
290 -
291 - _doEdit = function( page, fn, summary, doneFn ) {
292 - // Get an edit token for the page.
293 - var getTokenVars = {
294 - 'action':'query',
295 - 'prop':'info|revisions',
296 - 'intoken':'edit',
297 - 'titles':page,
298 - 'rvprop':'content|timestamp',
299 - 'format':'json'
300 - };
301 -
302 - $.get( mw.util.wikiScript( 'api' ), getTokenVars,
303 - function( reply ) {
304 - var infos = reply.query.pages;
305 - $.each(
306 - infos,
307 - function( pageid, data ) {
308 - var token = data.edittoken;
309 - var timestamp = data.revisions[0].timestamp;
310 - var oldText = data.revisions[0]['*'];
311 -
312 - var newText = fn( oldText );
313 -
314 - if ( newText === false ) return;
315 -
316 - var postEditVars = {
317 - 'action':'edit',
318 - 'title':page,
319 - 'text':newText,
320 - 'summary':summary,
321 - 'token':token,
322 - 'basetimestamp':timestamp,
323 - 'format':'json'
324 - };
325 -
326 - $.post( mw.util.wikiScript( 'api' ), postEditVars, doneFn, 'json' );
327 - }
328 - );
329 - }
330 - , 'json' );
331 - };
332 -
333 - /**
334 - * Append spinner wheel to element
335 - * @param DOMObject element.
336 - */
337 - _addProgressIndicator = function( elem ) {
338 - var indicator = $( '<div/>' );
339 -
340 - indicator.addClass( 'mw-ajax-loader' );
341 -
342 - elem.append( indicator );
343 - };
344 -
345 - /**
346 - * Find and remove spinner wheel from inside element
347 - * @param DOMObject parent element.
348 - */
349 - _removeProgressIndicator = function( elem ) {
350 - elem.find( '.mw-ajax-loader' ).remove();
351 - };
352 -
353 - /**
354 - * Makes regex string caseinsensitive.
355 - * Useful when 'i' flag can't be used.
356 - * Return stuff like [Ff][Oo][Oo]
357 - * @param string Regex string.
358 - * @return string Processed regex string
359 - */
360 - _makeCaseInsensitive = function( string ) {
361 - var newString = '';
362 - for (var i=0; i < string.length; i++) {
363 - newString += '[' + string[i].toUpperCase() + string[i].toLowerCase() + ']';
364 - }
365 - return newString;
366 - };
367 - _buildRegex = function( category ) {
368 - // Build a regex that matches legal invocations of that category.
369 - var categoryNSFragment = '';
370 - $.each( mw.config.get( 'wgNamespaceIds' ), function( name, id ) {
371 - if ( id == 14 ) {
372 - // The parser accepts stuff like cATegORy,
373 - // we need to do the same
374 - categoryNSFragment += '|' + _makeCaseInsensitive ( $.escapeRE(name) );
375 - }
376 - } );
377 - categoryNSFragment = categoryNSFragment.substr( 1 ); // Remove leading |
378 -
379 - // Build the regex
380 - var titleFragment = $.escapeRE(category);
381 -
382 - firstChar = category.charAt( 0 );
383 - firstChar = '[' + firstChar.toUpperCase() + firstChar.toLowerCase() + ']';
384 - titleFragment = firstChar + category.substr( 1 );
385 - var categoryRegex = '\\[\\[(' + categoryNSFragment + '):' + titleFragment + '(\\|[^\\]]*)?\\]\\]';
386 -
387 - return new RegExp( categoryRegex, 'g' );
388 - };
389 -
390 - _handleEditLink = function( e ) {
391 - e.preventDefault();
392 - var $this = $( this );
393 - var $link = $this.parent().find( 'a:not(.icon)' );
394 - var category = $link.text();
395 -
396 - var $input = _makeSuggestionBox( category,
397 - _handleCategoryEdit,
398 - _multiEdit ? mw.msg( 'ajax-confirm-ok' ) : mw.msg( 'ajax-confirm-save' )
399 - );
400 - $link.after( $input ).hide();
401 - $link.data('editButton').hide();
402 - $link.data('deleteButton').unbind('click').click( function() {
403 - $input.remove();
404 - $link.show();
405 - $link.data('editButton').show();
406 - $( this ).unbind('click').click( _handleDeleteLink );
407 - });
408 - };
409 -
410 - _handleAddLink = function( e ) {
411 - e.preventDefault();
412 -
413 - $container.find( '#mw-normal-catlinks>.mw-addcategory-prompt' ).toggle();
414 - };
415 -
416 - _handleDeleteLink = function( e ) {
417 - var $this = $( this );
418 - var $link = $this.parent().find( 'a:not(.icon)' );
419 - var category = $link.text();
420 -
421 - if ( $link.hasClass('mw-added-category') ) {
422 - // We're just cancelling the addition
423 - _removeStashItem ( $link );
424 -
425 - $link.parent().remove();
426 - return;
427 - }
428 -
429 - var categoryRegex = _buildRegex( category );
430 -
431 - var summary = mw.msg( 'ajax-remove-category-summary', category );
432 -
433 - _confirmEdit(
434 - function( oldText ) {
435 - newText = _runHooks ( oldText, 'beforeDelete' );
436 - //TODO Cleanup whitespace safely?
437 - var newText = newText.replace( categoryRegex, '' );
438 -
439 - if ( newText == oldText ) {
440 - var error = mw.msg( 'ajax-remove-category-error' );
441 - _showError( error );
442 - _removeProgressIndicator( $( '.mw-ajax-confirm-dialog' ) );
443 - $( '.mw-ajax-confirm-dialog' ).dialog( 'close' );
444 - return false;
445 - }
446 -
447 - return newText;
448 - },
449 - summary,
450 - function( unsaved ) {
451 - if ( unsaved ) {
452 - //TODO Make revertable
453 - $link.addClass('mw-removed-category');
454 - } else {
455 - $this.parent().remove();
456 - }
457 - },
458 - $link,
459 - 'delete'
460 - );
461 - };
462 -
463 - _handleCategoryAdd = function( e ) {
464 - var $this = $( this );
465 -
466 - // Grab category text
467 - var category = $this.parent().find( '.mw-addcategory-input' ).val();
468 - category = $.ucFirst( category );
469 -
470 - var $link = _createCatDOM( category );
471 -
472 - if ( aC.containsCat(category) ) {
473 - _showError( mw.msg( 'ajax-category-already-present', category ) );
474 - return;
475 - }
476 - var appendText = "\n[[" + new mw.Title( category, catNsId ) + "]]\n";
477 - var summary = mw.msg( 'ajax-add-category-summary', category );
478 -
479 - _confirmEdit(
480 - function( oldText ) {
481 - newText = _runHooks ( oldText, 'beforeAdd' );
482 - return newText + appendText;
483 - },
484 - summary,
485 - function( unsaved ) {
486 - $container.find( '#mw-normal-catlinks>.mw-addcategory-prompt' ).toggle();
487 - $container.find( '#mw-normal-catlinks ul' ).append( $link.parent() );
488 - if ( unsaved ) {
489 - $link.addClass( 'mw-added-category' );
490 - }
491 - },
492 - $link,
493 - 'add'
494 - );
495 - };
496 -
497 - _handleCategoryEdit = function( e ) {
498 - var $this = $( this );
499 -
500 - // Grab category text
501 - var categoryNew = $this.parent().find( '.mw-addcategory-input' ).val();
502 - categoryNew = $.ucFirst( categoryNew );
503 -
504 - var $link = $this.parent().parent().find( 'a:not(.icon)' );
505 - if ( $link.hasClass('mw-removed-category') ) {
506 - _removeStashItem ( $link );
507 - $link.removeClass( 'mw-removed-category' );
508 - }
509 - if ( $link.data( 'origCat' ) ) {
510 - var category = $link.data( 'origCat' );
511 - _removeStashItem ( $link );
512 - } else {
513 - var category = $link.text();
514 - }
515 -
516 -
517 - // User didn't change anything.
518 - if ( category == categoryNew ) {
519 - $link.data('deleteButton').click();
520 - return;
521 - }
522 - categoryRegex = _buildRegex( category );
523 -
524 - var summary = mw.msg( 'ajax-edit-category-summary', category, categoryNew );
525 -
526 - _confirmEdit(
527 - function( oldText ) {
528 - newText = _runHooks ( oldText, 'beforeChange' );
529 -
530 - var matches = newText.match( categoryRegex );
531 -
532 - //Old cat wasn't found, likely to be transcluded
533 - if ( !$.isArray( matches ) ) {
534 - var error = mw.msg( 'ajax-edit-category-error' );
535 - _showError( error );
536 - _removeProgressIndicator( $( '.mw-ajax-confirm-dialog' ) );
537 - $( '.mw-ajax-confirm-dialog' ).dialog( 'close' );
538 - return false;
539 - }
540 - var sortkey = matches[0].replace( categoryRegex, '$2' );
541 - var newCategoryString = "[[" + new mw.Titel( categoryNew, catNsId ) + sortkey + ']]';
542 -
543 - if (matches.length > 1) {
544 - // The category is duplicated.
545 - // Remove all but one match
546 - for (var i = 1; i < matches.length; i++) {
547 - oldText = oldText.replace( matches[i], '');
548 - }
549 - }
550 - var newText = oldText.replace( categoryRegex, newCategoryString );
551 -
552 - return newText;
553 - },
554 - summary,
555 - function( unsaved ) {
556 - // Remove input box & button
557 - $link.data('deleteButton').click();
558 -
559 - // Update link text and href
560 - $link.show().text( categoryNew ).attr( 'href', catLink( categoryNew ) );
561 - if ( unsaved ) {
562 - $link.data( 'origCat', category ).addClass( 'mw-changed-category' );
563 - }
564 - },
565 - $link,
566 - 'edit'
567 - );
568 - };
569 -
570 - /**
571 - * Open a dismissable error dialog
572 - *
573 - * @param string str The error description
574 - */
575 - _showError = function( str ) {
576 - var dialog = $( '<div/>' );
577 - dialog.text( str );
578 -
579 - mw.util.$content.append( dialog );
580 -
581 - var buttons = { };
582 - buttons[mw.msg( 'ajax-error-dismiss' )] = function( e ) {
583 - dialog.dialog( 'close' );
584 - };
585 - var dialogOptions = {
586 - 'buttons' : buttons,
587 - 'AutoOpen' : true,
588 - 'title' : mw.msg( 'ajax-error-title' )
589 - };
590 -
591 - dialog.dialog( dialogOptions );
592 - };
593 -
594 - /**
595 - * Manufacture iconed button, with or without text
596 - *
597 - * @param string icon The icon class.
598 - * @param string title Title attribute.
599 - * @param string className (optional) Additional classes to be added to the button.
600 - * @param string text (optional) Text of button.
601 - *
602 - * @return jQueryObject The button
603 - */
604 - _createButton = function( icon, title, className, text ){
605 - var $button = $( '<a>' ).addClass( className || '' )
606 - .attr('title', title);
607 -
608 - if ( text ) {
609 - var $icon = $( '<a>' ).addClass( 'icon ' + icon );
610 - $button.addClass( 'icon-parent' ).append( $icon ).append( text );
611 - } else {
612 - $button.addClass( 'icon ' + icon );
613 - }
614 - return $button;
615 - };
616 -
617 - /**
618 - * Append edit and remove buttons to a given category link
619 - *
620 - * @param DOMElement element Anchor element, to which the buttons should be appended.
621 - */
622 - _createCatButtons = function( element ) {
623 - // Create remove & edit buttons
624 - var deleteButton = _createButton('icon-close', mw.msg( 'ajax-remove-category' ) );
625 - var editButton = _createButton('icon-edit', mw.msg( 'ajax-edit-category' ) );
626 -
627 - //Not yet used
628 - var saveButton = _createButton('icon-tick', mw.msg( 'ajax-confirm-save' ) ).hide();
629 -
630 - deleteButton.click( _handleDeleteLink );
631 - editButton.click( _handleEditLink );
632 -
633 - $( element ).after( deleteButton ).after( editButton );
634 -
635 - //Save references to all links and buttons
636 - $( element ).data({
637 - saveButton : saveButton,
638 - deleteButton: deleteButton,
639 - editButton : editButton
640 - });
641 - };
642 - this.setup = function() {
643 - // Could be set by gadgets like HotCat etc.
644 - if ( mw.config.get('disableAJAXCategories') ) {
645 - return;
646 - }
647 - // Only do it for articles.
648 - if ( !mw.config.get( 'wgIsArticle' ) ) return;
649 -
650 - // Unhide hidden category holders.
651 - $('#mw-hidden-catlinks').show();
652 -
653 - var $li = $('<li>', {
654 - 'class' : 'mw-ajax-addcategory-holder'
655 - });
656 - // $containerNormal.find('ul').append( $li)
657 - // Create [Add Category] link
658 - var addLink = _createButton('icon-add',
659 - mw.msg( 'ajax-add-category' ),
660 - 'mw-ajax-addcategory',
661 - mw.msg( 'ajax-add-category' )
662 - );
663 - addLink.click( _handleAddLink );
664 - $containerNormal.append( addLink );
665 -
666 - // Create add category prompt
667 - var promptContainer = _makeSuggestionBox( '', _handleCategoryAdd, mw.msg( 'ajax-add-category-submit' ) );
668 - promptContainer.hide();
669 -
670 - // Create edit & delete link for each category.
671 - $( '#catlinks li a' ).each( function() {
672 - _createCatButtons( this );
673 - });
674 -
675 - $containerNormal.append( promptContainer );
676 -
677 - //TODO Make more clickable
678 - _saveAllButton = _createButton( 'icon-tick',
679 - mw.msg( 'ajax-confirm-save-all' ),
680 - '',
681 - mw.msg( 'ajax-confirm-save-all' )
682 - );
683 - _cancelAllButton = _createButton( 'icon-tick',
684 - mw.msg( 'ajax-confirm-save-all' ),
685 - '',
686 - mw.msg( 'ajax-confirm-save-all' )
687 - );
688 - _saveAllButton.click( _handleStashedCategories ).hide();
689 - _cancelAllButton.hide();
690 - //TODO wrap in div display:inline-block
691 - $containerNormal.append( _saveAllButton ).append( _cancelAllButton );
692 - };
693 -
694 - _stash = {
695 - summaries : [],
696 - fns : []
697 - };
698 - _removeStashItem = function( $link ) {
699 - var i = $link.data( 'stashIndex' );
700 - delete _stash.fns[i];
701 - delete _stash.summaries[i];
702 - }
703 - _hooks = {
704 - beforeAdd : [],
705 - beforeChange : [],
706 - beforeDelete : []
707 - };
708 - _runHooks = function( oldtext, type ) {
709 - // No hooks registered
710 - if ( !_hooks[type] ) {
711 - return oldtext;
712 - } else {
713 - for (var i = 0; i < _hooks[type].length; i++) {
714 - oldtext = _hooks[type][i]( oldtext );
715 - }
716 - return oldtext;
717 - }
718 - };
719 - /**
720 - * Add hooks
721 - * Currently available: beforeAdd, beforeChange, beforeDelete
722 - *
723 - * @param string type Type of hook to add
724 - * @param function fn Hook function. This function is the old text passed
725 - * and it needs to return the modified text
726 - */
727 - this.addHook = function( type, fn ) {
728 - if ( !_hooks[type] ) return;
729 - else hooks[type].push( fn );
730 - };
731 -};
732 -
733 -} )( jQuery );
\ No newline at end of file
Index: branches/REL1_18/phase3/resources/mediawiki.page/mediawiki.page.ajaxCategories.init.js
@@ -1 +0,0 @@
2 -jQuery( document ).ready( new mw.ajaxCategories().setup );

Status & tagging log