Implemented console panel in debug toolbar
authorJohn Du Hart <johnduhart@users.mediawiki.org>
Tue, 3 Jan 2012 05:56:36 +0000 (05:56 +0000)
committerJohn Du Hart <johnduhart@users.mediawiki.org>
Tue, 3 Jan 2012 05:56:36 +0000 (05:56 +0000)
includes/GlobalFunctions.php
includes/debug/Debug.php
resources/mediawiki/mediawiki.debug.css
resources/mediawiki/mediawiki.debug.js

index c97c722..231dc65 100644 (file)
@@ -3460,7 +3460,9 @@ function wfGetNull() {
  */
 function wfDeprecated( $function, $version = false, $component = false ) {
        static $functionsWarned = array();
-       
+
+       MWDebug::deprecated( $function, $version, $component );
+
        if ( !in_array( $function, $GLOBALS['wgDeprecationWhitelist'] ) && !isset( $functionsWarned[$function] ) ) {
                $functionsWarned[$function] = true;
                
@@ -3501,6 +3503,8 @@ function wfDeprecated( $function, $version = false, $component = false ) {
 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
        global $wgDevelopmentWarnings;
 
+       MWDebug::warning( $msg, $callerOffset + 2 );
+
        $callers = wfDebugBacktrace();
        if ( isset( $callers[$callerOffset + 1] ) ) {
                $callerfunc = $callers[$callerOffset + 1];
index abda29b..6766f8c 100644 (file)
@@ -42,6 +42,14 @@ class MWDebug {
         */
        protected static $enabled = true;
 
+       /**
+        * Array of functions that have already been warned, formatted
+        * function-caller to prevent a buttload of warnings
+        *
+        * @var array
+        */
+       protected static $deprecationWarnings = array();
+
        /**
         * Called in Setup.php, initializes the debugger if it is enabled with
         * $wgDebugToolbar
@@ -60,9 +68,6 @@ class MWDebug {
        /**
         * Adds a line to the log
         *
-        * This does nothing atm, there's not frontend for it
-        *
-        * @todo Add error and warning log type
         * @todo Add support for passing objects
         *
         * @param $str string
@@ -72,7 +77,75 @@ class MWDebug {
                        return;
                }
 
-               self::$log[] = $str;
+               self::$log[] = array(
+                       'msg' => htmlspecialchars( $str ),
+                       'type' => 'log',
+                       'caller' => wfGetCaller(),
+               );
+       }
+
+       /**
+        * Adds a warning entry to the log
+        *
+        * @param $msg
+        * @param int $callerOffset
+        * @return mixed
+        */
+       public static function warning( $msg, $callerOffset = 1 ) {
+               if ( !self::$enabled ) {
+                       return;
+               }
+
+               // Check to see if there was already a deprecation notice, so not to
+               // get a duplicate warning
+               $lastLog = self::$log[ count( self::$log ) - 1 ];
+               if ( $lastLog['type'] == 'deprecated' && $lastLog['caller'] == wfGetCaller( $callerOffset + 1 ) ) {
+                       return;
+               }
+
+               self::$log[] = array(
+                       'msg' => htmlspecialchars( $msg ),
+                       'type' => 'warn',
+                       'caller' => wfGetCaller( $callerOffset ),
+               );
+       }
+
+       /**
+        * Adds a depreciation entry to the log, along with a backtrace
+        *
+        * @param $function
+        * @param $version
+        * @param $component
+        * @return mixed
+        */
+       public static function deprecated( $function, $version, $component ) {
+               if ( !self::$enabled ) {
+                       return;
+               }
+
+               // Chain: This function -> wfDeprecated -> deprecatedFunction -> caller
+               $caller = wfGetCaller( 4 );
+
+               // Check to see if there already was a warning about this function
+               $functionString = "$function-$caller";
+               if ( in_array( $functionString, self::$deprecationWarnings ) ) {
+                       return;
+               }
+
+               $version = $version === false ? '(unknown version)' : $version;
+               $component = $component === false ? 'MediaWiki' : $component;
+               $msg = htmlspecialchars( "Use of function $function was deprecated in $component $version" );
+               $msg .= Html::rawElement( 'div', array( 'class' => 'mw-debug-backtrace' ),
+                       Html::element( 'span', array(), 'Backtrace:' )
+                        . wfBacktrace()
+               );
+
+               self::$deprecationWarnings[] = $functionString;
+               self::$log[] = array(
+                       'msg' => $msg,
+                       'type' => 'deprecated',
+                       'caller' => $caller,
+               );
        }
 
        /**
@@ -178,6 +251,7 @@ class MWDebug {
                }
 
                global $wgVersion, $wgRequestTime;
+               MWDebug::log( 'MWDebug output complete' );
                $debugInfo = array(
                        'mwVersion' => $wgVersion,
                        'phpVersion' => PHP_VERSION,
index fe25e75..efc56b8 100644 (file)
@@ -88,7 +88,7 @@ a.mw-debug-panelabel:visited {
 }
 
 .mw-debug-pane {
-       max-height: 300px;
+       height: 300px;
        overflow: scroll;
        display: none;
        font-size: 11px;
@@ -129,3 +129,49 @@ a.mw-debug-panelabel:visited {
 #mw-debug-pane-request td {
        background-color: white;
 }
+
+#mw-debug-console tr td:first-child {
+       font-weight: bold;
+       vertical-align: top;
+}
+
+.mw-debug-console-log {
+       background-color: #add8e6;
+}
+
+.mw-debug-console-warn {
+       background-color: #ffa07a;
+}
+
+.mw-debug-console-deprecated {
+       background-color: #ffb6c1;
+}
+
+.mw-debug-backtrace {
+       padding: 5px 10px;
+       margin: 5px;
+       background-color: #dedede;
+}
+
+.mw-debug-backtrace span {
+       font-weight: bold;
+       color: #111;
+}
+
+.mw-debug-backtrace ul {
+       padding-left: 10px;
+}
+
+.mw-debug-backtrace li {
+       width: auto;
+       padding: 0;
+       color: #333;
+       font-size: 10px;
+       margin-bottom: 0;
+       line-height: 1em;
+}
+
+/* Cheapo hack to hide the first 3 lines of the backtrace */
+.mw-debug-backtrace li:nth-child(-n+3) {
+       display: none;
+}
\ No newline at end of file
index ce9affe..df2a922 100644 (file)
                                .appendTo( $bits );
                        }
 
+                       paneTriggerBitDiv( 'console', 'Console (' + this.data.log.length + ')' );
+
                        paneTriggerBitDiv( 'querylist', 'Queries: ' + this.data.queries.length );
 
                        paneTriggerBitDiv( 'debuglog', 'Debug Log (' + this.data.debugLog.length + ' lines)' );
                        $bits.appendTo( $container );
 
                        panes = {
+                               console: this.buildConsoleTable(),
                                querylist: this.buildQueryTable(),
                                debuglog: this.buildDebugLogTable(),
                                request: this.buildRequestPane(),
                        this.$container = $container;
                },
 
+               /**
+                * Builds the console panel
+                */
+               buildConsoleTable: function () {
+                       var $table, entryTypeText, i, length, entry;
+
+                       $table = $( '<table id="mw-debug-console">' );
+
+                       $('<colgroup>').css( 'width', /*padding=*/20 + ( 10*/*fontSize*/11 ) ).appendTo( $table );
+                       $('<colgroup>').appendTo( $table );
+                       $('<colgroup>').css( 'width', 350 ).appendTo( $table );
+
+
+                       entryTypeText = function( entryType ) {
+                               switch ( entryType ) {
+                                       case 'log':
+                                               return 'Log';
+                                       case 'warn':
+                                               return 'Warning';
+                                       case 'deprecated':
+                                               return 'Deprecated';
+                                       default:
+                                               return 'Unknown';
+                               }
+                       };
+
+                       for ( i = 0, length = this.data.log.length; i < length; i += 1 ) {
+                               entry = this.data.log[i];
+                               entry.typeText = entryTypeText( entry.type );
+
+                               $( '<tr>' )
+                                       .append( $( '<td>' )
+                                               .text( entry.typeText )
+                                               .attr( 'class', 'mw-debug-console-' + entry.type )
+                                       )
+                                       .append( $( '<td>' ).html( entry.msg ) )
+                                       .append( $( '<td>' ).text( entry.caller ) )
+                                       .appendTo( $table );
+                       }
+
+                       return $table;
+               },
+
                /**
                 * Query list pane
                 */