Merge "Add and update some missing release notes for rl modules."
authorCatrope <roan.kattouw@gmail.com>
Thu, 30 Aug 2012 21:09:43 +0000 (21:09 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 30 Aug 2012 21:09:43 +0000 (21:09 +0000)
includes/LinksUpdate.php
includes/SqlDataUpdate.php
includes/filebackend/FileBackendStore.php
resources/jquery/jquery.badge.css
resources/jquery/jquery.badge.js

index 1d0bcf7..87db4d6 100644 (file)
@@ -51,7 +51,7 @@ class LinksUpdate extends SqlDataUpdate {
         * @param $recursive Boolean: queue jobs for recursive updates?
         */
        function __construct( $title, $parserOutput, $recursive = true ) {
-               parent::__construct( );
+               parent::__construct( false ); // no implicit transaction
 
                if ( !( $title instanceof Title ) ) {
                        throw new MWException( "The calling convention to LinksUpdate::LinksUpdate() has changed. " .
@@ -825,7 +825,7 @@ class LinksDeletionUpdate extends SqlDataUpdate {
         * @param $page WikiPage Page we are updating
         */
        function __construct( WikiPage $page ) {
-               parent::__construct( );
+               parent::__construct( false ); // no implicit transaction
 
                $this->mPage = $page;
        }
index aeb9ba4..52c9be0 100644 (file)
@@ -36,11 +36,16 @@ abstract class SqlDataUpdate extends DataUpdate {
        protected $mOptions;       //!< SELECT options to be used (array)
 
        private   $mHasTransaction; //!< bool whether a transaction is open on this object (internal use only!)
+       protected $mUseTransaction; //!< bool whether this update should be wrapped in a transaction
 
        /**
         * Constructor
-       **/
-       public function __construct( ) {
+        *
+        * @param bool $withTransaction whether this update should be wrapped in a transaction (default: true).
+        *             A transaction is only started if no transaction is already in progress,
+        *             see beginTransaction() for details.
+        **/
+       public function __construct( $withTransaction = true ) {
                global $wgAntiLockFlags;
 
                parent::__construct( );
@@ -53,16 +58,22 @@ abstract class SqlDataUpdate extends DataUpdate {
 
                // @todo: get connection only when it's needed? make sure that doesn't break anything, especially transactions!
                $this->mDb = wfGetDB( DB_MASTER );
+
+               $this->mWithTransaction = $withTransaction;
                $this->mHasTransaction = false;
        }
 
        /**
-        * Begin a database transaction.
+        * Begin a database transaction, if $withTransaction was given as true in the constructor for this SqlDataUpdate.
         *
-        * Because nested transactions are not supportred by the Database class, this implementation
-        * checkes Database::trxLevel() and only opens a transaction if none is yet active.
+        * Because nested transactions are not supported by the Database class, this implementation
+        * checks Database::trxLevel() and only opens a transaction if none is already active.
         */
        public function beginTransaction() {
+               if ( !$this->mWithTransaction ) {
+                       return;
+               }
+
                // NOTE: nested transactions are not supported, only start a transaction if none is open
                if ( $this->mDb->trxLevel() === 0 ) {
                        $this->mDb->begin( get_class( $this ) . '::beginTransaction'  );
@@ -76,6 +87,7 @@ abstract class SqlDataUpdate extends DataUpdate {
        public function commitTransaction() {
                if ( $this->mHasTransaction ) {
                        $this->mDb->commit( get_class( $this ) . '::commitTransaction' );
+                       $this->mHasTransaction = false;
                }
        }
 
@@ -85,6 +97,7 @@ abstract class SqlDataUpdate extends DataUpdate {
        public function abortTransaction() {
                if ( $this->mHasTransaction ) {
                        $this->mDb->rollback( get_class( $this ) . '::abortTransaction' );
+                       $this->mHasTransaction = false;
                }
        }
 
index 9bec145..d53f7b3 100644 (file)
@@ -105,7 +105,9 @@ abstract class FileBackendStore extends FileBackend {
                } else {
                        $status = $this->doCreateInternal( $params );
                        $this->clearCache( array( $params['dst'] ) );
-                       $this->deleteFileCache( $params['dst'] ); // persistent cache
+                       if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+                               $this->deleteFileCache( $params['dst'] ); // persistent cache
+                       }
                }
                wfProfileOut( __METHOD__ . '-' . $this->name );
                wfProfileOut( __METHOD__ );
@@ -141,7 +143,9 @@ abstract class FileBackendStore extends FileBackend {
                } else {
                        $status = $this->doStoreInternal( $params );
                        $this->clearCache( array( $params['dst'] ) );
-                       $this->deleteFileCache( $params['dst'] ); // persistent cache
+                       if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+                               $this->deleteFileCache( $params['dst'] ); // persistent cache
+                       }
                }
                wfProfileOut( __METHOD__ . '-' . $this->name );
                wfProfileOut( __METHOD__ );
@@ -173,7 +177,9 @@ abstract class FileBackendStore extends FileBackend {
                wfProfileIn( __METHOD__ . '-' . $this->name );
                $status = $this->doCopyInternal( $params );
                $this->clearCache( array( $params['dst'] ) );
-               $this->deleteFileCache( $params['dst'] ); // persistent cache
+               if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+                       $this->deleteFileCache( $params['dst'] ); // persistent cache
+               }
                wfProfileOut( __METHOD__ . '-' . $this->name );
                wfProfileOut( __METHOD__ );
                return $status;
@@ -235,7 +241,9 @@ abstract class FileBackendStore extends FileBackend {
                $status = $this->doMoveInternal( $params );
                $this->clearCache( array( $params['src'], $params['dst'] ) );
                $this->deleteFileCache( $params['src'] ); // persistent cache
-               $this->deleteFileCache( $params['dst'] ); // persistent cache
+               if ( !empty( $params['overwrite'] ) ) { // file possibly mutated
+                       $this->deleteFileCache( $params['dst'] ); // persistent cache
+               }
                wfProfileOut( __METHOD__ . '-' . $this->name );
                wfProfileOut( __METHOD__ );
                return $status;
@@ -1460,7 +1468,9 @@ abstract class FileBackendStore extends FileBackend {
        }
 
        /**
-        * Set the cached stat info for a file path
+        * Set the cached stat info for a file path.
+        * Negatives (404s) are not cached. By not caching negatives, we can skip cache
+        * salting for the case when a file is created at a path were there was none before.
         *
         * @param $path string Storage path
         * @param $val mixed Information to cache
index 49063ba..92e7255 100644 (file)
@@ -2,19 +2,19 @@
        min-width: 8px;
        height: 14px;
        border: 1px solid white;
-       border-radius: 8px;
        -moz-border-radius: 8px;
        -webkit-border-radius: 8px;
-       box-shadow: 0px 1px 4px #ccc;
+       border-radius: 8px;
        -moz-box-shadow: 0px 1px 4px #ccc;
        -webkit-box-shadow: 0px 1px 4px #ccc;
+       box-shadow: 0px 1px 4px #ccc;
        background-color: #b60a00;
-       background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
        background-image: -o-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
        background-image: -moz-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
+       background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00));
        background-image: -webkit-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
        background-image: -ms-linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
-       background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #a70802), color-stop(1, #cf0e00));
+       background-image: linear-gradient(bottom, #a70802 0%, #cf0e00 100%);
        padding: 0 3px;
        text-align: center;
 }
index d40acc6..04495b7 100644 (file)
@@ -1,9 +1,16 @@
-// Badger v1.0 by Daniel Raftery
-// http://thrivingkings.com/badger
-// http://twitter.com/ThrivingKings
-// Modified by Ryan Kaldari <rkaldari@wikimedia.org>
+/**
+ * jQuery Badge plugin
+ *
+ * Based on Badger plugin by Daniel Raftery (http://thrivingkings.com/badger).
+ *
+ * @license MIT
+ */
 
 /**
+ * @author Ryan Kaldari <rkaldari@wikimedia.org>, 2012
+ * @author Andrew Garrett <agarrett@wikimedia.org>, 2012
+ * @author Marius Hoch <hoo@online.de>, 2012
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  *
  * This program is distributed WITHOUT ANY WARRANTY.
  */
+( function ( $ ) {
 
-(function( $ ) {
-       $.fn.badge = function( badge, options ) {
-               var existingBadge = this.find( '.mw-badge' );
-               options = $.extend( {}, options );
+       /**
+        * Allows you to put a numeric "badge" on an item on the page.
+        * See mediawiki.org/wiki/ResourceLoader/Default_modules#jQuery.badge
+        *
+        * @param {string|number} badgeCount An explicit number, or "+n"/ "-n"
+        *  to modify the existing value. If the new value is equal or lower than 0,
+        *  any existing badge will be removed. The badge container will be appended
+        *  to the selected element(s).
+        * @param {Object} options Optional parameters specified below
+        *   type: 'inline' or 'overlay' (default)
+        *   callback: will be called with the number now shown on the badge as a parameter
+        */
+       $.fn.badge = function ( badgeCount, options ) {
+               var $badge,
+                       oldBadgeCount,
+                       newBadgeCount,
+                       $existingBadge = this.find( '.mw-badge' );
 
-               badge = String(badge);
-               if ( badge.charAt(0) === '+' ) {
-                       if ( existingBadge.length > 0 ) {
-                               oldBadge = existingBadge.text();
-                               badge = Math.round( Number( oldBadge ) + Number( badge.substr(1) ) );
-                       } else {
-                               badge = badge.substr(1);
-                       }
-               } else if ( badge.charAt(0) === '-' ) {
-                       if ( existingBadge.length > 0 ) {
-                               oldBadge = existingBadge.text();
-                               badge = Math.round( Number( oldBadge ) - Number( badge.substr(1) ) );
+               options = $.extend( { type : 'overlay' }, options );
+
+               // If there is no existing badge, this will give an empty string
+               oldBadgeCount = Number( $existingBadge.text() );
+               if ( isNaN( oldBadgeCount ) ) {
+                       oldBadgeCount = 0;
+               }
+
+               // If badgeCount is a number, use that as the new badge
+               if ( typeof badgeCount === 'number' ) {
+                       newBadgeCount = badgeCount;
+               } else if ( typeof badgeCount === 'string' ) {
+                       // If badgeCount is "+x", add x to the old badge
+                       if ( badgeCount.charAt(0) === '+' ) {
+                               newBadgeCount = oldBadgeCount + Number( badgeCount.substr(1) );
+                       // If badgeCount is "-x", subtract x from the old badge
+                       } else if ( badgeCount.charAt(0) === '-' ) {
+                               newBadgeCount = oldBadgeCount - Number( badgeCount.substr(1) );
+                       // If badgeCount can be converted into a number, convert it
+                       } else if ( !isNaN( Number( badgeCount ) ) ) {
+                               newBadgeCount = Number( badgeCount );
                        } else {
-                               badge = 0;
+                               newBadgeCount = 0;
                        }
+               // Other types are not supported, fall back to 0.
+               } else {
+                       newBadgeCount = 0;
                }
 
-               if ( Number(badge) <= 0 ) {
-                       // Clear any existing badge
-                       existingBadge.remove();
+               // Badge count must be a whole number
+               newBadgeCount = Math.round( newBadgeCount );
+
+               if ( newBadgeCount <= 0 ) {
+                       // Badges should only exist for values > 0.
+                       $existingBadge.remove();
                } else {
                        // Don't add duplicates
-                       var $badge = existingBadge;
-                       if ( existingBadge.length > 0 ) {
-                               this.find( '.mw-badge-content' ).text( badge );
+                       if ( $existingBadge.length ) {
+                               $badge = $existingBadge;
+                               // Insert the new count into the badge
+                               this.find( '.mw-badge-content' ).text( newBadgeCount );
                        } else {
-                               $badge = $('<div/>')
-                                       .addClass('mw-badge')
-                                       .addClass('mw-badge-overlay')
+                               // Contruct a new badge with the count
+                               $badge = $( '<div>' )
+                                       .addClass( 'mw-badge' )
                                        .append(
-                                               $('<span/>')
-                                                       .addClass('mw-badge-content')
-                                                       .text(badge)
+                                               $( '<span>' )
+                                                       .addClass( 'mw-badge-content' )
+                                                       .text( newBadgeCount )
                                        );
-                               this.append($badge);
+                               this.append( $badge );
                        }
 
-                       if ( options.type ) {
-                               if ( options.type == 'inline' ) {
-                                       $badge.removeClass('mw-badge-overlay')
-                                               .addClass('mw-badge-inline');
-                               } else if ( options.type == 'overlay' ) {
-                                       $badge.removeClass('mw-badge-inline')
-                                               .addClass('mw-badge-overlay');
-                               }
+                       if ( options.type === 'inline' ) {
+                               $badge
+                                       .removeClass( 'mw-badge-overlay' )
+                                       .addClass( 'mw-badge-inline' );
+                       // Default: overlay
+                       } else {
+                               $badge
+                                       .removeClass( 'mw-badge-inline' )
+                                       .addClass( 'mw-badge-overlay' );
+
                        }
 
-                       // If a callback was specified, call it with the badge number
-                       if ( options.callback ) {
-                               options.callback( badge );
+                       // If a callback was specified, call it with the badge count
+                       if ( $.isFunction( options.callback ) ) {
+                               options.callback( newBadgeCount );
                        }
                }
        };
-} ) ( jQuery );
+}( jQuery ) );