Index: trunk/phase3/resources/mediawiki.page/mediawiki.page.ajaxCategories.js |
— | — | @@ -4,26 +4,24 @@ |
5 | 5 | // Something like: "Category:Foo added. Reason" |
6 | 6 | // Requirement: Be able to get msg with lang option. |
7 | 7 | // * Handle uneditable cats. Needs serverside changes! |
8 | | -// * Add Hooks for soft redirect |
9 | 8 | // * Handle normal redirects |
10 | | - |
11 | | -// * Fixme on narrow windows |
12 | 9 | // * Enter to submit |
13 | 10 | |
14 | 11 | ( function( $, mw ) { |
15 | 12 | |
16 | 13 | var ajaxCategories = function ( options ) { |
| 14 | + //Save scope in shortcut |
| 15 | + var aC = this; |
| 16 | + |
17 | 17 | // TODO grab these out of option object. |
18 | 18 | |
19 | 19 | var catLinkWrapper = '<li/>'; |
20 | 20 | var $container = $( '.catlinks' ); |
21 | 21 | var $containerNormal = $( '#mw-normal-catlinks' ); |
22 | 22 | |
23 | | - var categoryLinkSelector = '#mw-normal-catlinks li a'; |
| 23 | + var categoryLinkSelector = '#mw-normal-catlinks li a:not(.icon)'; |
24 | 24 | var _request; |
25 | 25 | |
26 | | - var _catElements = {}; |
27 | | - |
28 | 26 | var namespaceIds = mw.config.get( 'wgNamespaceIds' ); |
29 | 27 | var categoryNamespaceId = namespaceIds['category']; |
30 | 28 | var categoryNamespace = mw.config.get( 'wgFormattedNamespaces' )[categoryNamespaceId]; |
— | — | @@ -75,9 +73,9 @@ |
76 | 74 | * Insert a newly added category into the DOM |
77 | 75 | * |
78 | 76 | * @param string category name. |
79 | | - * @param boolean isHidden (unused) |
| 77 | + * @return jQuery object |
80 | 78 | */ |
81 | | - _insertCatDOM = function ( cat, isHidden ) { |
| 79 | + _createCatDOM = function ( cat ) { |
82 | 80 | // User can implicitely state a sort key. |
83 | 81 | // Remove before display |
84 | 82 | cat = cat.replace(/\|.*/, ''); |
— | — | @@ -85,7 +83,7 @@ |
86 | 84 | // strip out bad characters |
87 | 85 | cat = _stripIllegals ( cat ); |
88 | 86 | |
89 | | - if ( $.isEmpty( cat ) || this.containsCat( cat ) ) { |
| 87 | + if ( $.isEmpty( cat ) || aC.containsCat( cat ) ) { |
90 | 88 | return; |
91 | 89 | } |
92 | 90 | |
— | — | @@ -93,12 +91,10 @@ |
94 | 92 | var $anchor = $( '<a/>' ).append( cat ); |
95 | 93 | $catLinkWrapper.append( $anchor ); |
96 | 94 | $anchor.attr( { target: "_blank", href: _catLink( cat ) } ); |
97 | | - if ( isHidden ) { |
98 | | - $container.find( '#mw-hidden-catlinks ul' ).append( $catLinkWrapper ); |
99 | | - } else { |
100 | | - $container.find( '#mw-normal-catlinks ul' ).append( $catLinkWrapper ); |
101 | | - } |
| 95 | + |
102 | 96 | _createCatButtons( $anchor.get(0) ); |
| 97 | + |
| 98 | + return $anchor; |
103 | 99 | }; |
104 | 100 | |
105 | 101 | _makeSuggestionBox = function ( prefill, callback, buttonVal ) { |
— | — | @@ -162,7 +158,7 @@ |
163 | 159 | }; |
164 | 160 | |
165 | 161 | /** |
166 | | - * This get's called by all action buttons |
| 162 | + * This gets called by all action buttons |
167 | 163 | * Displays a dialog to confirm the action |
168 | 164 | * Afterwords do the actual edit |
169 | 165 | * |
— | — | @@ -171,13 +167,15 @@ |
172 | 168 | * @param function fn doneFn callback after everything is done |
173 | 169 | * @return boolean True for exists |
174 | 170 | */ |
175 | | - _confirmEdit = function ( fn, actionSummary, doneFn, all ) { |
| 171 | + _confirmEdit = function ( fn, actionSummary, doneFn, $link, action ) { |
176 | 172 | // Check whether to use multiEdit mode |
177 | | - if ( _multiEdit && !all ) { |
| 173 | + if ( _multiEdit && action != 'all' ) { |
178 | 174 | // Stash away |
| 175 | + $link.data('stashIndex', _stash.fns.length ); |
179 | 176 | _stash.summaries.push( actionSummary ); |
180 | 177 | _stash.fns.push( fn ); |
181 | 178 | |
| 179 | + |
182 | 180 | //TODO add Cancel button |
183 | 181 | _saveAllButton.show(); |
184 | 182 | //_cancelAllButton.show(); |
— | — | @@ -249,19 +247,25 @@ |
250 | 248 | // Save fns |
251 | 249 | fns = _stash.fns; |
252 | 250 | |
253 | | - // RTL? |
254 | | - var summary = _stash.summaries.join('. '); |
| 251 | + //TODO Add spaces in msg |
| 252 | + var summary = _stash.summaries.join(); |
| 253 | + if ( summary == '' ) { |
| 254 | + _saveAllButton.hide(); |
| 255 | + return; |
| 256 | + } |
255 | 257 | var combinedFn = function( oldtext ) { |
256 | 258 | // Run the text through all action functions |
257 | 259 | newtext = oldtext; |
258 | 260 | for ( var i = 0; i < fns.length; i++ ) { |
259 | | - newtext = fns[i]( newtext ); |
| 261 | + if ( $.isFunction ( fns[i] ) ) { |
| 262 | + newtext = fns[i]( newtext ); |
| 263 | + } |
260 | 264 | } |
261 | 265 | return newtext; |
262 | 266 | }; |
263 | 267 | var doneFn = _resetToActual; |
264 | 268 | |
265 | | - _confirmEdit( combinedFn, summary, doneFn, true ); |
| 269 | + _confirmEdit( combinedFn, summary, doneFn, '', 'all' ); |
266 | 270 | }; |
267 | 271 | |
268 | 272 | _resetToActual = function() { |
— | — | @@ -390,11 +394,11 @@ |
391 | 395 | _multiEdit ? mw.msg( 'ajax-confirm-ok' ) : mw.msg( 'ajax-confirm-save' ) |
392 | 396 | ); |
393 | 397 | $link.after( $input ).hide(); |
394 | | - _catElements[category].editButton.hide(); |
395 | | - _catElements[category].deleteButton.unbind('click').click( function() { |
| 398 | + $link.data('editButton').hide(); |
| 399 | + $link.data('deleteButton').unbind('click').click( function() { |
396 | 400 | $input.remove(); |
397 | 401 | $link.show(); |
398 | | - _catElements[category].editButton.show(); |
| 402 | + $link.data('editButton').show(); |
399 | 403 | $( this ).unbind('click').click( _handleDeleteLink ); |
400 | 404 | }); |
401 | 405 | }; |
— | — | @@ -406,12 +410,18 @@ |
407 | 411 | }; |
408 | 412 | |
409 | 413 | _handleDeleteLink = function ( e ) { |
410 | | - e.preventDefault(); |
411 | | - |
412 | 414 | var $this = $( this ); |
413 | 415 | var $link = $this.parent().find( 'a:not(.icon)' ); |
414 | 416 | var category = $link.text(); |
415 | 417 | |
| 418 | + if ( $link.hasClass('mw-added-category') ) { |
| 419 | + // We're just cancelling the addition |
| 420 | + _removeStashItem ( $link ); |
| 421 | + |
| 422 | + $link.parent().remove(); |
| 423 | + return; |
| 424 | + } |
| 425 | + |
416 | 426 | var categoryRegex = _buildRegex( category ); |
417 | 427 | |
418 | 428 | var summary = mw.msg( 'ajax-remove-category-summary', category ); |
— | — | @@ -436,20 +446,26 @@ |
437 | 447 | function( unsaved ) { |
438 | 448 | if ( unsaved ) { |
439 | 449 | //TODO Make revertable |
440 | | - $link.addClass('.mw-removed-category'); |
| 450 | + $link.addClass('mw-removed-category'); |
441 | 451 | } else { |
442 | 452 | $this.parent().remove(); |
443 | 453 | } |
444 | | - } |
| 454 | + }, |
| 455 | + $link, |
| 456 | + 'delete' |
445 | 457 | ); |
446 | 458 | }; |
447 | 459 | |
448 | 460 | _handleCategoryAdd = function ( e ) { |
| 461 | + var $this = $( this ); |
| 462 | + |
449 | 463 | // Grab category text |
450 | | - var category = $( this ).parent().find( '.mw-addcategory-input' ).val(); |
| 464 | + var category = $this.parent().find( '.mw-addcategory-input' ).val(); |
451 | 465 | category = $.ucFirst( category ); |
452 | 466 | |
453 | | - if ( this.containsCat(category) ) { |
| 467 | + var $link = _createCatDOM( category ); |
| 468 | + |
| 469 | + if ( aC.containsCat(category) ) { |
454 | 470 | _showError( mw.msg( 'ajax-category-already-present', category ) ); |
455 | 471 | return; |
456 | 472 | } |
— | — | @@ -462,28 +478,41 @@ |
463 | 479 | return newText + appendText; |
464 | 480 | }, |
465 | 481 | summary, |
466 | | - function() { |
| 482 | + function( unsaved ) { |
467 | 483 | $container.find( '#mw-normal-catlinks>.mw-addcategory-prompt' ).toggle(); |
468 | | - _insertCatDOM( category, false ); |
469 | | - } |
| 484 | + $container.find( '#mw-normal-catlinks ul' ).append( $link.parent() ); |
| 485 | + if ( unsaved ) { |
| 486 | + $link.addClass( 'mw-added-category' ); |
| 487 | + } |
| 488 | + }, |
| 489 | + $link, |
| 490 | + 'add' |
470 | 491 | ); |
471 | 492 | }; |
472 | 493 | |
473 | 494 | _handleCategoryEdit = function ( e ) { |
474 | | - //FIXME: in MultiEdit Mode handle successive edits to same category |
475 | | - e.preventDefault(); |
| 495 | + var $this = $( this ); |
476 | 496 | |
477 | 497 | // Grab category text |
478 | | - var categoryNew = $( this ).parent().find( '.mw-addcategory-input' ).val(); |
| 498 | + var categoryNew = $this.parent().find( '.mw-addcategory-input' ).val(); |
479 | 499 | categoryNew = $.ucFirst( categoryNew ); |
480 | 500 | |
481 | | - var $this = $( this ); |
482 | 501 | var $link = $this.parent().parent().find( 'a:not(.icon)' ); |
483 | | - var category = $link.text(); |
| 502 | + if ( $link.hasClass('mw-removed-category') ) { |
| 503 | + _removeStashItem ( $link ); |
| 504 | + $link.removeClass( 'mw-removed-category' ); |
| 505 | + } |
| 506 | + if ( $link.data( 'origCat' ) ) { |
| 507 | + var category = $link.data( 'origCat' ); |
| 508 | + _removeStashItem ( $link ); |
| 509 | + } else { |
| 510 | + var category = $link.text(); |
| 511 | + } |
| 512 | + |
484 | 513 | |
485 | 514 | // User didn't change anything. |
486 | 515 | if ( category == categoryNew ) { |
487 | | - _catElements[category].deleteButton.click(); |
| 516 | + $link.data('deleteButton').click(); |
488 | 517 | return; |
489 | 518 | } |
490 | 519 | categoryRegex = _buildRegex( category ); |
— | — | @@ -519,14 +548,18 @@ |
520 | 549 | return newText; |
521 | 550 | }, |
522 | 551 | summary, |
523 | | - function() { |
| 552 | + function( unsaved ) { |
524 | 553 | // Remove input box & button |
525 | | - _catElements[category].deleteButton.click(); |
526 | | - _catElements[categoryNew] = _catElements[category]; |
527 | | - delete _catElements[category]; |
| 554 | + $link.data('deleteButton').click(); |
| 555 | + |
528 | 556 | // Update link text and href |
529 | 557 | $link.show().text( categoryNew ).attr( 'href', _catLink( categoryNew ) ); |
530 | | - } |
| 558 | + if ( unsaved ) { |
| 559 | + $link.data( 'origCat', category ).addClass( 'mw-changed-category' ); |
| 560 | + } |
| 561 | + }, |
| 562 | + $link, |
| 563 | + 'edit' |
531 | 564 | ); |
532 | 565 | }; |
533 | 566 | |
— | — | @@ -596,13 +629,11 @@ |
597 | 630 | $( element ).after( deleteButton ).after( editButton ); |
598 | 631 | |
599 | 632 | //Save references to all links and buttons |
600 | | - _catElements[$( element ).text()] = { |
601 | | - link : $( element ), |
602 | | - parent : $( element ).parent(), |
| 633 | + $( element ).data({ |
603 | 634 | saveButton : saveButton, |
604 | 635 | deleteButton: deleteButton, |
605 | 636 | editButton : editButton |
606 | | - }; |
| 637 | + }); |
607 | 638 | }; |
608 | 639 | this.setup = function () { |
609 | 640 | // Could be set by gadgets like HotCat etc. |
— | — | @@ -615,6 +646,10 @@ |
616 | 647 | // Unhide hidden category holders. |
617 | 648 | $('#mw-hidden-catlinks').show(); |
618 | 649 | |
| 650 | + var $li = $('<li>', { |
| 651 | + 'class' : 'mw-ajax-addcategory-holder' |
| 652 | + }); |
| 653 | + // $containerNormal.find('ul').append( $li) |
619 | 654 | // Create [Add Category] link |
620 | 655 | var addLink = _createButton('icon-add', |
621 | 656 | mw.msg( 'ajax-add-category' ), |
— | — | @@ -629,7 +664,7 @@ |
630 | 665 | promptContainer.hide(); |
631 | 666 | |
632 | 667 | // Create edit & delete link for each category. |
633 | | - $( '#catlinks li a' ).each( function( e ) { |
| 668 | + $( '#catlinks li a' ).each( function() { |
634 | 669 | _createCatButtons( this ); |
635 | 670 | }); |
636 | 671 | |
— | — | @@ -648,7 +683,7 @@ |
649 | 684 | ); |
650 | 685 | _saveAllButton.click( _handleStashedCategories ).hide(); |
651 | 686 | _cancelAllButton.hide(); |
652 | | - |
| 687 | + //TODO wrap in div display:inline-block |
653 | 688 | $containerNormal.append( _saveAllButton ).append( _cancelAllButton ); |
654 | 689 | }; |
655 | 690 | |
— | — | @@ -656,6 +691,11 @@ |
657 | 692 | summaries : [], |
658 | 693 | fns : [] |
659 | 694 | }; |
| 695 | + _removeStashItem = function ( $link ) { |
| 696 | + var i = $link.data( 'stashIndex' ); |
| 697 | + delete _stash.fns[i]; |
| 698 | + delete _stash.summaries[i]; |
| 699 | + } |
660 | 700 | _hooks = { |
661 | 701 | beforeAdd : [], |
662 | 702 | beforeChange : [], |