From de96e923680e543c89d4f2533e48a7c261230ef1 Mon Sep 17 00:00:00 2001 From: Leo Koppelkamm Date: Wed, 13 Jul 2011 22:36:03 +0000 Subject: [PATCH] Rewrite ajaxCategories for ResourceLoader. Add some missing functionality (edit categories and more). Move styles from shared.css into own stylesheet. Fix regex bugs --- includes/DefaultSettings.php | 13 + includes/OutputPage.php | 16 +- languages/messages/MessagesEn.php | 20 + maintenance/language/messages.inc | 19 + resources/Resources.php | 25 + .../images/AJAXCategorySprite.png | Bin 0 -> 384 bytes .../mediawiki.page.ajaxCategories.css | 62 ++ .../mediawiki.page.ajaxCategories.js | 603 ++++++++++++------ skins/common/shared.css | 26 - 9 files changed, 548 insertions(+), 236 deletions(-) create mode 100644 resources/mediawiki.page/images/AJAXCategorySprite.png create mode 100644 resources/mediawiki.page/mediawiki.page.ajaxCategories.css diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 7cbb25ac39..9123ec8f19 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -5500,6 +5500,19 @@ $wgSeleniumConfigFile = null; $wgDBtestuser = ''; //db user that has permission to create and drop the test databases only $wgDBtestpassword = ''; +/** + * Whether or not to use the AJAX categories system. + */ +$wgUseAJAXCategories = false; + +/** + * Only enable AJAXCategories on configured namespaces. Default is all. + * + * Example: + * $wgAJAXCategoriesNamespaces = array( NS_MAIN, NS_PROJECT ); + */ +$wgAJAXCategoriesNamespaces = array(); + /** * For really cool vim folding this needs to be at the end: * vim: foldmarker=@{,@} foldmethod=marker diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 82d082a339..79ceefe79f 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2340,8 +2340,8 @@ $templates * Add the default ResourceLoader modules to this object */ private function addDefaultModules() { - global $wgIncludeLegacyJavaScript, - $wgUseAjax, $wgAjaxWatch, $wgEnableMWSuggest; + global $wgIncludeLegacyJavaScript, $wgUseAjax, + $wgAjaxWatch, $wgEnableMWSuggest, $wgUseAJAXCategories; // Add base resources $this->addModules( array( @@ -2369,9 +2369,19 @@ $templates } } - if( $this->getUser()->getBoolOption( 'editsectiononrightclick' ) ) { + if ( $this->getUser()->getBoolOption( 'editsectiononrightclick' ) ) { $this->addModules( 'mediawiki.action.view.rightClickEdit' ); } + + if ( $wgUseAJAXCategories ) { + global $wgAJAXCategoriesNamespaces; + + $title = $this->getTitle(); + + if( empty( $wgAJAXCategoriesNamespaces ) || in_array( $title->getNamespace(), $wgAJAXCategoriesNamespaces ) ) { + $this->addModules( 'mediawiki.page.ajaxCategories' ); + } + } } /** diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index badda888b2..68e148d518 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -4586,4 +4586,24 @@ This site is experiencing technical difficulties.', 'sqlite-has-fts' => '$1 with full-text search support', 'sqlite-no-fts' => '$1 without full-text search support', + +# Add categories per AJAX +'ajax-add-category' => 'Add category', +'ajax-remove-category' => 'Remove category', +'ajax-edit-category' => 'Edit category', +'ajax-add-category-submit' => 'Add', +'ajax-confirm-title' => 'Confirm action', +'ajax-confirm-prompt' => 'You can provide an edit summary below. +Click "Save" to save your edit.', +'ajax-confirm-save' => 'Save', +'ajax-add-category-summary' => 'Add category "$1"', +'ajax-edit-category-summary' => 'Change category "$1" to "$2"', +'ajax-remove-category-summary' => 'Remove category "$1"', +'ajax-confirm-actionsummary' => 'Action to take:', +'ajax-error-title' => 'Error', +'ajax-error-dismiss' => 'OK', +'ajax-remove-category-error' => 'It was not possible to remove this category. +This usually occurs when the category has been added to the page in a template.', +'ajax-edit-category-error' => 'It was not possible to edit this category. +This usually occurs when the category has been added to the page in a template.', ); diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index c67b7934bd..efc3fa956a 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -3459,6 +3459,24 @@ $wgMessageStructure = array( 'unwatch' => array( 'confirm-unwatch-button', ), + 'ajax-category' => array( + 'ajax-add-category', + 'ajax-remove-category', + 'ajax-edit-category', + 'ajax-add-category-submit', + 'ajax-confirm-title', + 'ajax-confirm-prompt', + 'ajax-confirm-save', + 'ajax-add-category-summary', + 'ajax-edit-category-summary', + 'ajax-remove-category-summary', + 'ajax-confirm-actionsummary', + 'ajax-error-title', + 'ajax-error-dismiss', + 'ajax-remove-category-error', + 'ajax-edit-category-error', + ), + ); /** Comments for each block */ @@ -3687,4 +3705,5 @@ Variants for Chinese language", 'db-error-messages' => 'Database error messages', 'html-forms' => 'HTML forms', 'sqlite' => 'SQLite database support', + 'ajax-category' => 'Add categories per AJAX', ); diff --git a/resources/Resources.php b/resources/Resources.php index f2692dc1b2..9bc4b8f0c5 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -483,6 +483,31 @@ return array( 'jquery.ui.autocomplete', ), ), + 'mediawiki.page.ajaxCategories' => array( + 'scripts' => 'resources/mediawiki.page/mediawiki.page.ajaxCategories.js', + 'styles' => 'resources/mediawiki.page/mediawiki.page.ajaxCategories.css', + 'dependencies' => array( + 'jquery.suggestions', + 'jquery.ui.dialog', + ), + 'messages' => array( + 'ajax-add-category', + 'ajax-remove-category', + 'ajax-edit-category', + 'ajax-add-category-submit', + 'ajax-confirm-prompt', + 'ajax-confirm-title', + 'ajax-confirm-save', + 'ajax-add-category-summary', + 'ajax-remove-category-summary', + 'ajax-edit-category-summary', + 'ajax-confirm-actionsummary', + 'ajax-error-title', + 'ajax-error-dismiss', + 'ajax-remove-category-error', + 'ajax-edit-category-error', + ), + ), 'mediawiki.libs.jpegmeta' => array( 'scripts' => 'resources/mediawiki.libs/mediawiki.libs.jpegmeta.js', ), diff --git a/resources/mediawiki.page/images/AJAXCategorySprite.png b/resources/mediawiki.page/images/AJAXCategorySprite.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f9cf48efc278326f3fab552a7ff3f266f3f378 GIT binary patch literal 384 zcmV-`0e}99P)OCbON0Z=j94X$Y?xp!!^Q($@K3geXUQ&xUqWcg)?_2cZNs5PFfu0f; zJV|*k-ZZbs(Wd^ z*8Hj>p3hc_mzUJyjp#lE(EAp>c#`6wSD>ea1y54mi#N?K?A>v#c%gRT2' ).append( cat ); + $catLinkWrapper.append( $anchor ); + $anchor.attr( { target: "_blank", href: _catLink( cat ) } ); + if ( isHidden ) { + $container.find( '#mw-hidden-catlinks ul' ).append( $catLinkWrapper ); + } else { + $container.find( '#mw-normal-catlinks ul' ).append( $catLinkWrapper ); + } + _createCatButtons( $anchor.get(0) ); + } + + function _makeSuggestionBox( prefill, callback, buttonVal ) { + // Create add category prompt + var promptContainer = $( '
' ); + var promptTextbox = $( '' ); + if ( prefill !== '' ) { + promptTextbox.val( prefill ); + } + var addButton = $( '' ); + addButton.val( buttonVal ); + + addButton.click( callback ); + + promptTextbox.suggestions( { + 'fetch':_fetchSuggestions, + 'cancel': function() { + var req = _request; + // XMLHttpRequest.abort is unimplemented in IE6, also returns nonstandard value of "unknown" for typeof + if ( req && ( typeof req.abort !== 'unknown' ) && ( typeof req.abort !== 'undefined' ) && req.abort ) { + req.abort(); + } + } + } ); - reloadCategoryList : function( response ) { - var holder = $j( '
' ); + promptTextbox.suggestions(); - holder.load( - window.location.href + ' .catlinks', - function() { - $j( '.catlinks' ).replaceWith( holder.find( '.catlinks' ) ); - ajaxCategories.setupAJAXCategories(); - ajaxCategories.removeProgressIndicator( $j( '.catlinks' ) ); - } - ); - }, + promptContainer.append( promptTextbox ); + promptContainer.append( addButton ); - confirmEdit : function( page, fn, actionSummary, doneFn ) { - // Load jQuery UI - mvJsLoader.doLoad( - ['$j.ui', '$j.ui.dialog', '$j.fn.suggestions'], - function() { - // Produce a confirmation dialog - - var dialog = $j( '
' ); - - dialog.addClass( 'mw-ajax-confirm-dialog' ); - dialog.attr( 'title', gM( 'ajax-confirm-title' ) ); - - // Intro text. - var confirmIntro = $j( '

' ); - confirmIntro.text( gM( 'ajax-confirm-prompt' ) ); - dialog.append( confirmIntro ); - - // Summary of the action to be taken - var summaryHolder = $j( '

' ); - var summaryLabel = $j( '' ); - summaryLabel.text( gM( 'ajax-confirm-actionsummary' ) + " " ); - summaryHolder.text( actionSummary ); - summaryHolder.prepend( summaryLabel ); - dialog.append( summaryHolder ); - - // Reason textbox. - var reasonBox = $j( '' ); - reasonBox.addClass( 'mw-ajax-confirm-reason' ); - dialog.append( reasonBox ); - - // Submit button - var submitButton = $j( '' ); - submitButton.val( gM( 'ajax-confirm-save' ) ); - - var submitFunction = function() { - ajaxCategories.addProgressIndicator( dialog ); - ajaxCategories.doEdit( - page, - fn, - reasonBox.val(), - function() { - doneFn(); - dialog.dialog( 'close' ); - ajaxCategories.removeProgressIndicator( dialog ); - } - ); - }; - - var buttons = { }; - buttons[gM( 'ajax-confirm-save' )] = submitFunction; - var dialogOptions = { - 'AutoOpen' : true, - 'buttons' : buttons, - 'width' : 450 - }; - - $j( '#catlinks' ).prepend( dialog ); - dialog.dialog( dialogOptions ); - } - ); - }, + return promptContainer; + } + + // Create a valid link to the category. + function _catLink ( cat ) { + //SYNCED + return mw.util.wikiGetlink( categoryNamespace + ':' + $.ucFirst( cat ) ); + } + + function _getCats() { + return $container.find( categoryLinkSelector ).map( function() { return $.trim( $( this ).text() ); } ); + } - doEdit : function( page, fn, summary, doneFn ) { + function _containsCat( cat ) { + //TODO: SYNC + return _getCats().filter( function() { return $.ucFirst(this) == $.ucFirst(cat); } ).length !== 0; + } + + function _confirmEdit ( page, fn, actionSummary, doneFn ) { + + // Produce a confirmation dialog + var dialog = $( '

' ); + + dialog.addClass( 'mw-ajax-confirm-dialog' ); + dialog.attr( 'title', mw.msg( 'ajax-confirm-title' ) ); + + // Intro text. + var confirmIntro = $( '

' ); + confirmIntro.text( mw.msg( 'ajax-confirm-prompt' ) ); + dialog.append( confirmIntro ); + + // Summary of the action to be taken + var summaryHolder = $( '

' ); + var summaryLabel = $( '' ); + summaryLabel.text( mw.msg( 'ajax-confirm-actionsummary' ) + " " ); + summaryHolder.text( actionSummary ); + summaryHolder.prepend( summaryLabel ); + dialog.append( summaryHolder ); + + // Reason textbox. + var reasonBox = $( '' ); + reasonBox.addClass( 'mw-ajax-confirm-reason' ); + dialog.append( reasonBox ); + + // Submit button + var submitButton = $( '' ); + submitButton.val( mw.msg( 'ajax-confirm-save' ) ); + + var submitFunction = function() { + _addProgressIndicator( dialog ); + _doEdit( + page, + fn, + reasonBox.val(), + function() { + doneFn(); + dialog.dialog( 'close' ); + _removeProgressIndicator( dialog ); + } + ); + }; + + var buttons = { }; + buttons[mw.msg( 'ajax-confirm-save' )] = submitFunction; + var dialogOptions = { + 'AutoOpen' : true, + 'buttons' : buttons, + 'width' : 450 + }; + + $( '#catlinks' ).prepend( dialog ); + dialog.dialog( dialogOptions ); + } + + function _doEdit ( page, fn, summary, doneFn ) { // Get an edit token for the page. var getTokenVars = { 'action':'query', @@ -151,10 +198,10 @@ var ajaxCategories = { 'format':'json' }; - $j.get( wgScriptPath + '/api.php', getTokenVars, + $.get( wgScriptPath + '/api.php', getTokenVars, function( reply ) { var infos = reply.query.pages; - $j.each( + $.each( infos, function( pageid, data ) { var token = data.edittoken; @@ -175,152 +222,294 @@ var ajaxCategories = { 'format':'json' }; - $j.post( wgScriptPath + '/api.php', postEditVars, doneFn, 'json' ); + $.post( wgScriptPath + '/api.php', postEditVars, doneFn, 'json' ); } ); } , 'json' ); - }, + } - addProgressIndicator : function( elem ) { - var indicator = $j( '

' ); + function _addProgressIndicator ( elem ) { + var indicator = $( '
' ); indicator.addClass( 'mw-ajax-loader' ); elem.append( indicator ); - }, + } - removeProgressIndicator : function( elem ) { + function _removeProgressIndicator ( elem ) { elem.find( '.mw-ajax-loader' ).remove(); - }, - - handleCategoryAdd : function( e ) { - // Grab category text - var category = $j( '#mw-addcategory-input' ).val(); - var appendText = "\n[[" + wgFormattedNamespaces[14] + ":" + category + "]]\n"; - var summary = gM( 'ajax-add-category-summary', category ); - - ajaxCategories.confirmEdit( - wgPageName, - function( oldText ) { return oldText + appendText }, - summary, - ajaxCategories.reloadCategoryList - ); - }, - - handleDeleteLink : function( e ) { - e.preventDefault(); - - var category = $j( this ).parent().find( 'a' ).text(); - + } + + function _makeCaseInsensitiv( string ) { + var newString = ''; + for (var i=0; i < string.length; i++) { + newString += '[' + string[i].toUpperCase() + string[i].toLowerCase() + ']'; + }; + return newString; + } + function _buildRegex ( category ) { // Build a regex that matches legal invocations of that category. - - // In theory I should escape the aliases, but there's no JS function for it - // Shouldn't have any real impact, can't be exploited or anything, so we'll - // leave it for now. var categoryNSFragment = ''; - $j.each( wgNamespaceIds, function( name, id ) { + $.each( namespaceIds, function( name, id ) { if ( id == 14 ) { - // Allow the first character to be any case - var firstChar = name.charAt( 0 ); - firstChar = '[' + firstChar.toUpperCase() + firstChar.toLowerCase() + ']'; - categoryNSFragment += '|' + firstChar + name.substr( 1 ); + // The parser accepts stuff like cATegORy, + // we need to do the same + categoryNSFragment += '|' + _makeCaseInsensitiv ( $.escapeRE(name) ); } } ); categoryNSFragment = categoryNSFragment.substr( 1 ); // Remove leading | - + // Build the regex - var titleFragment = category; + var titleFragment = $.escapeRE(category); firstChar = category.charAt( 0 ); firstChar = '[' + firstChar.toUpperCase() + firstChar.toLowerCase() + ']'; titleFragment = firstChar + category.substr( 1 ); - var categoryRegex = '\\[\\[' + categoryNSFragment + ':' + titleFragment + '(\\|[^\\]]*)?\\]\\]'; - categoryRegex = new RegExp( categoryRegex, 'g' ); + var categoryRegex = '\\[\\[(' + categoryNSFragment + '):' + titleFragment + '(\\|[^\\]]*)?\\]\\]'; + + return new RegExp( categoryRegex, 'g' ); + } + + function _handleEditLink ( e ) { + e.preventDefault(); + var $this = $( this ); + var $link = $this.parent().find( 'a:not(.icon)' ); + var category = $link.text(); + + var $input = _makeSuggestionBox( category, _handleCategoryEdit, mw.msg( 'ajax-confirm-save' ) ); + $link.after( $input ).hide(); + _catElements[category].editButton.hide(); + _catElements[category].deleteButton.unbind('click').click( function() { + $input.remove(); + $link.show(); + _catElements[category].editButton.show(); + $( this ).unbind('click').click( _handleDeleteLink ); + }); + } + + function _handleAddLink ( e ) { + e.preventDefault(); + + $container.find( '#mw-normal-catlinks>.mw-addcategory-prompt' ).toggle(); + } + + function _handleDeleteLink ( e ) { + e.preventDefault(); - var summary = gM( 'ajax-remove-category-summary', category ); + var $this = $( this ); + var $link = $this.parent().find( 'a:not(.icon)' ); + var category = $link.text(); - ajaxCategories.confirmEdit( - wgPageName, + categoryRegex = _buildRegex( category ); + + var summary = mw.msg( 'ajax-remove-category-summary', category ); + + _confirmEdit( + mw.config.get('wgPageName'), function( oldText ) { + //TODO Cleanup whitespace safely? var newText = oldText.replace( categoryRegex, '' ); if ( newText == oldText ) { - var error = gM( 'ajax-remove-category-error' ); - ajaxCategories.showError( error ); - ajaxCategories.removeProgressIndicator( $j( '.mw-ajax-confirm-dialog' ) ); - $j( '.mw-ajax-confirm-dialog' ).dialog( 'close' ); + var error = mw.msg( 'ajax-remove-category-error' ); + _showError( error ); + _removeProgressIndicator( $( '.mw-ajax-confirm-dialog' ) ); + $( '.mw-ajax-confirm-dialog' ).dialog( 'close' ); return false; } return newText; }, - summary, ajaxCategories.reloadCategoryList + summary, + function() { + $this.parent().remove(); + } ); - }, + } - showError : function( str ) { - var dialog = $j( '
' ); + function _handleCategoryAdd ( e ) { + // Grab category text + var category = $( this ).parent().find( '.mw-addcategory-input' ).val(); + category = $.ucFirst( category ); + + if ( _containsCat(category) ) { + // TODO add info alert + return; + } + var appendText = "\n[[" + categoryNamespace + ":" + category + "]]\n"; + var summary = mw.msg( 'ajax-add-category-summary', category ); + + _confirmEdit( + mw.config.get( 'wgPageName' ), + function( oldText ) { return oldText + appendText }, + summary, + function() { + _insertCatDOM( category, false ); + } + ); + } + + function _handleCategoryEdit ( e ) { + e.preventDefault(); + + // Grab category text + var categoryNew = $( this ).parent().find( '.mw-addcategory-input' ).val(); + categoryNew = $.ucFirst( categoryNew ); + + var $this = $( this ); + var $link = $this.parent().parent().find( 'a:not(.icon)' ); + var category = $link.text(); + + // User didn't change anything. Just close the box + if ( category == categoryNew ) { + $this.parent().remove(); + $link.show(); + return; + } + categoryRegex = _buildRegex( category ); + + var summary = mw.msg( 'ajax-edit-category-summary', category, categoryNew ); + + _confirmEdit( + mw.config.get( 'wgPageName' ), + function( oldText ) { + var matches = oldText.match( categoryRegex ); + + //Old cat wasn't found, likely to be transcluded + if ( !$.isArray( matches ) ) { + var error = mw.msg( 'ajax-edit-category-error' ); + _showError( error ); + _removeProgressIndicator( $( '.mw-ajax-confirm-dialog' ) ); + $( '.mw-ajax-confirm-dialog' ).dialog( 'close' ); + return false; + } + var sortkey = matches[0].replace( categoryRegex, '$2' ); + var newCategoryString = "[[" + categoryNamespace + ":" + categoryNew + sortkey + ']]'; + + if (matches.length > 1) { + // The category is duplicated. + // Remove all but one match + for (var i = 1; i < matches.length; i++) { + oldText = oldText.replace( matches[i], ''); + } + } + var newText = oldText.replace( categoryRegex, newCategoryString ); + + return newText; + }, + summary, + function() { + // Remove input box & button + $this.parent().remove(); + + // Update link text and href + $link.show().text( categoryNew ).attr( 'href', _catLink( categoryNew ) ); + } + ); + } + function _showError ( str ) { + var dialog = $( '
' ); dialog.text( str ); - $j( '#bodyContent' ).append( dialog ); + $( '#bodyContent' ).append( dialog ); var buttons = { }; - buttons[gM( 'ajax-error-dismiss' )] = function( e ) { + buttons[mw.msg( 'ajax-error-dismiss' )] = function( e ) { dialog.dialog( 'close' ); }; var dialogOptions = { 'buttons' : buttons, 'AutoOpen' : true, - 'title' : gM( 'ajax-error-title' ) + 'title' : mw.msg( 'ajax-error-title' ) }; dialog.dialog( dialogOptions ); - }, + } - setupAJAXCategories : function() { + function _createButton ( icon, title, category, text ){ + var button = $( '' ).addClass( category || '' ) + .attr('title', title); + + if ( text ) { + var icon = $( '' ).addClass( 'icon ' + icon ); + button.addClass( 'icon-parent' ).append( icon ).append( text ); + } else { + button.addClass( 'icon ' + icon ); + } + return button; + } + function _createCatButtons ( element ) { + // Create remove & edit buttons + var deleteButton = _createButton('icon-close', mw.msg( 'ajax-remove-category' ) ); + var editButton = _createButton('icon-edit', mw.msg( 'ajax-edit-category' ) ); + + //Not yet used + var saveButton = _createButton('icon-tick', mw.msg( 'ajax-confirm-save' ) ).hide(); + + deleteButton.click( _handleDeleteLink ); + editButton.click( _handleEditLink ); + + $( element ).after( deleteButton ).after( editButton ); + + //Save references to all links and buttons + _catElements[$( element ).text()] = { + link : $( element ), + parent : $( element ).parent(), + saveButton : saveButton, + deleteButton: deleteButton, + editButton : editButton + }; + } + function _setup() { + // Could be set by gadgets like HotCat etc. + if ( mw.config.get('disableAJAXCategories') ) { + return; + } // Only do it for articles. - if ( !wgIsArticle ) return; + if ( !mw.config.get( 'wgIsArticle' ) ) return; - var clElement = $j( '.catlinks' ); + var clElement = $( '#mw-normal-catlinks' ); // Unhide hidden category holders. - clElement.removeClass( 'catlinks-allhidden' ); + $('#mw-hidden-catlinks').show(); - var addLink = $j( '' ); - addLink.addClass( 'mw-ajax-addcategory' ); // Create [Add Category] link - addLink.text( gM( 'ajax-add-category' ) ); - addLink.attr( 'href', '#' ); - addLink.click( ajaxCategories.handleAddLink ); + var addLink = _createButton('icon-add', + mw.msg( 'ajax-add-category' ), + 'mw-ajax-addcategory', + mw.msg( 'ajax-add-category' ) + ); + addLink.click( _handleAddLink ); clElement.append( addLink ); // Create add category prompt - var promptContainer = $j( '
' ); - var promptTextbox = $j( '' ); - var addButton = $j( '' ); - addButton.val( gM( 'ajax-add-category-submit' ) ); - - promptTextbox.keypress( ajaxCategories.handleCategoryInput ); - addButton.click( ajaxCategories.handleCategoryAdd ); - - promptContainer.append( promptTextbox ); - promptContainer.append( addButton ); + var promptContainer = _makeSuggestionBox( '', _handleCategoryAdd, mw.msg( 'ajax-add-category-submit' ) ); promptContainer.hide(); - // Create delete link for each category. - $j( '.catlinks div span a' ).each( function( e ) { - // Create a remove link - var deleteLink = $j( '' ); - - deleteLink.click( ajaxCategories.handleDeleteLink ); - - $j( this ).after( deleteLink ); - } ); + // Create edit & delete link for each category. + $( '#catlinks li a' ).each( function( e ) { + _createCatButtons( this ); + }); clElement.append( promptContainer ); } -}; + function _teardown() { + + } + _tasks = { + list : [], + executed : [], + add : function( obj ) { + this.list.push( obj ); + }, + next : function() { + var task = this.list.shift(); + //run task + this.executed.push( task ); + } + } + $(document).ready( function() {_setup()}); -js2AddOnloadHook( ajaxCategories.setupAJAXCategories ); +} )( jQuery, mediaWiki ); \ No newline at end of file diff --git a/skins/common/shared.css b/skins/common/shared.css index b08853c9b4..0ff29bc02e 100644 --- a/skins/common/shared.css +++ b/skins/common/shared.css @@ -583,32 +583,6 @@ div.gallerytext { word-wrap: break-word; } -#mw-addcategory-prompt { - display: inline; - margin-left: 1em; -} - -#mw-addcategory-prompt input { - margin-left: 0.5em; - margin-right: 0.5em; -} - -.mw-remove-category { - padding: 8px; - /* @embed */ - background-image: url(images/remove.png); - background-position: center center; - background-repeat: no-repeat; -} - -.mw-ajax-addcategory { - padding-left: 20px; - /* @embed */ - background-image: url(images/add.png); - background-position: left center; - background-repeat: no-repeat; -} - .mw-ajax-loader { /* @embed */ background-image: url(images/ajax-loader.gif); -- 2.20.1