r83891 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83890‎ | r83891 | r83892 >
Date:13:24, 14 March 2011
Author:catrope
Status:ok
Tags:
Comment:
Followup r83885: implement maximum line length and statement termination (each statement on its own line) in JavaScriptMinifier. Also add globals for these things and update minify.php for these new config vars.
Modified paths:
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/libs/JavaScriptMinifier.php (modified) (history)
  • /trunk/phase3/includes/resourceloader/ResourceLoader.php (modified) (history)
  • /trunk/phase3/maintenance/minify.php (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/minify.php
@@ -35,9 +35,12 @@
3636 "Directory for output. If this is not specified, and neither is --outfile, then the\n" .
3737 "output files will be sent to the same directories as the input files.",
3838 false, true );
39 - $this->addOption( 'minify-vertical-space',
40 - "Boolean value for minifying the vertical space for javascript.",
 39+ $this->addOption( 'js-statements-on-own-line',
 40+ "Boolean value for putting statements on their own line when minifying JavaScript.",
4141 false, true );
 42+ $this->addOption( 'js-max-line-length',
 43+ "Maximum line length for JavaScript minification.",
 44+ false, true );
4245 $this->mDescription = "Minify a file or set of files.\n\n" .
4346 "If --outfile is not specified, then the output file names will have a .min extension\n" .
4447 "added, e.g. jquery.js -> jquery.min.js.";
@@ -99,7 +102,7 @@
100103 }
101104
102105 public function minify( $inPath, $outPath ) {
103 - global $wgResourceLoaderMinifyJSVerticalSpace;
 106+ global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength;
104107
105108 $extension = $this->getExtension( $inPath );
106109 $this->output( basename( $inPath ) . ' -> ' . basename( $outPath ) . '...' );
@@ -117,7 +120,10 @@
118121
119122 switch ( $extension ) {
120123 case 'js':
121 - $outText = JavaScriptDistiller::stripWhiteSpace( $inText, $this->getOption( 'minify-vertical-space', $wgResourceLoaderMinifyJSVerticalSpace ) );
 124+ $outText = JavaScriptMinifier::minify( $inText,
 125+ $this->getOption( 'js-statements-on-own-line', $wgResourceLoaderMinifierStatementsOnOwnLine ),
 126+ $this->getOption( 'js-max-line-length', $wgResourceLoaderMinifierMaxLineLength )
 127+ );
122128 break;
123129 case 'css':
124130 $outText = CSSMin::minify( $inText );
Index: trunk/phase3/includes/resourceloader/ResourceLoader.php
@@ -121,6 +121,7 @@
122122 * @return String: Filtered data, or a comment containing an error message
123123 */
124124 protected function filter( $filter, $data ) {
 125+ global $wgResourceLoaderMinifierStatementsOnOwnLine, $wgResourceLoaderMinifierMaxLineLength;
125126 wfProfileIn( __METHOD__ );
126127
127128 // For empty/whitespace-only data or for unknown filters, don't perform
@@ -147,7 +148,10 @@
148149 try {
149150 switch ( $filter ) {
150151 case 'minify-js':
151 - $result = JavaScriptMinifier::minify( $data );
 152+ $result = JavaScriptMinifier::minify( $data,
 153+ $wgResourceLoaderMinifierStatementsOnOwnLine,
 154+ $wgResourceLoaderMinifierMaxLineLength
 155+ );
152156 $result .= "\n\n/* cache key: $key */\n";
153157 break;
154158 case 'minify-css':
Index: trunk/phase3/includes/libs/JavaScriptMinifier.php
@@ -66,10 +66,16 @@
6767 /**
6868 * Returns minified JavaScript code.
6969 *
 70+ * NOTE: $maxLineLength isn't a strict maximum. Longer lines will be produced when
 71+ * literals (e.g. quoted strings) longer than $maxLineLength are encountered
 72+ * or when required to guard against semicolon insertion.
 73+ *
7074 * @param $s String JavaScript code to minify
 75+ * @param $statementsOnOwnLine Bool Whether to put each statement on its own line
 76+ * @param $maxLineLength Int Maximum length of a single line, or -1 for no maximum.
7177 * @return String Minified code
7278 */
73 - public static function minify( $s ) {
 79+ public static function minify( $s, $statementsOnOwnLine = false, $maxLineLength = 1000 ) {
7480 // First we declare a few tables that contain our parsing rules
7581
7682 // $opChars : characters, which can be combined without whitespace in between them
@@ -377,6 +383,23 @@
378384 self::TYPE_LITERAL => true
379385 )
380386 );
 387+
 388+ // Rules for when newlines should be inserted if
 389+ // $statementsOnOwnLine is enabled.
 390+ // $newlineBefore is checked before switching state,
 391+ // $newlineAfter is checked after
 392+ $newlineBefore = array(
 393+ self::STATEMENT => array(
 394+ self::TYPE_BRACE_CLOSE => true,
 395+ ),
 396+ );
 397+ $newlineAfter = array(
 398+ self::STATEMENT => array(
 399+ self::TYPE_BRACE_OPEN => true,
 400+ self::TYPE_PAREN_CLOSE => true,
 401+ self::TYPE_SEMICOLON => true,
 402+ ),
 403+ );
381404
382405 // $divStates : Contains all states that can be followed by a division operator
383406 $divStates = array(
@@ -391,6 +414,7 @@
392415 $out = '';
393416 $pos = 0;
394417 $length = strlen( $s );
 418+ $lineLength = 0;
395419 $newlineFound = true;
396420 $state = self::STATEMENT;
397421 $stack = array();
@@ -492,7 +516,7 @@
493517 }
494518
495519 // Now get the token type from our type array
496 - $token = substr( $s, $pos, $end - $pos );
 520+ $token = substr( $s, $pos, $end - $pos ); // so $end - $pos == strlen( $token )
497521 $type = isset( $tokenTypes[$token] ) ? $tokenTypes[$token] : self::TYPE_LITERAL;
498522
499523 if( $newlineFound && isset( $semicolon[$state][$type] ) ) {
@@ -500,20 +524,38 @@
501525 // could add the ; token here ourselves, keeping the newline has a few advantages.
502526 $out .= "\n";
503527 $state = self::STATEMENT;
504 - } elseif( false /* Put your newline condition here */ ) {
 528+ $lineLength = 0;
 529+ } elseif( $maxLineLength > 0 && $lineLength + $end - $pos > $maxLineLength &&
 530+ !isset( $semicolon[$state][$type] ) )
 531+ {
 532+ // This line would get too long if we added $token, so add a newline first.
 533+ // Only do this if it won't trigger semicolon insertion though.
505534 $out .= "\n";
 535+ $lineLength = 0;
506536 // Check, whether we have to separate the token from the last one with whitespace
507537 } elseif( !isset( $opChars[$last] ) && !isset( $opChars[$ch] ) ) {
508538 $out .= ' ';
 539+ $lineLength++;
509540 // Don't accidentally create ++, -- or // tokens
510541 } elseif( $last === $ch && ( $ch === '+' || $ch === '-' || $ch === '/' ) ) {
511542 $out .= ' ';
 543+ $lineLength++;
512544 }
513545
514546 $out .= $token;
 547+ $lineLength += $end - $pos; // += strlen( $token )
515548 $last = $s[$end - 1];
516549 $pos = $end;
517550 $newlineFound = false;
 551+
 552+ // Output a newline after the token if required
 553+ // This is checked before AND after switching state
 554+ $newlineAdded = false;
 555+ if ( $statementsOnOwnLine && !$newlineAdded && isset( $newlineBefore[$state][$type] ) ) {
 556+ $out .= "\n";
 557+ $lineLength = 0;
 558+ $newlineAdded = true;
 559+ }
518560
519561 // Now that we have output our token, transition into the new state.
520562 if( isset( $push[$state][$type] ) && count( $stack ) < self::STACK_LIMIT ) {
@@ -524,6 +566,12 @@
525567 } elseif( isset( $goto[$state][$type] ) ) {
526568 $state = $goto[$state][$type];
527569 }
 570+
 571+ // Check for newline insertion again
 572+ if ( $statementsOnOwnLine && !$newlineAdded && isset( $newlineAfter[$state][$type] ) ) {
 573+ $out .= "\n";
 574+ $lineLength = 0;
 575+ }
528576 }
529577 return $out;
530578 }
Index: trunk/phase3/includes/DefaultSettings.php
@@ -2505,12 +2505,19 @@
25062506 $wgResourceLoaderUseESI = false;
25072507
25082508 /**
2509 - * Enable removal of some of the vertical whitespace (like \r and \n) from
2510 - * JavaScript code when minifying.
 2509+ * Put each statement on its own line when minifying JavaScript. This makes
 2510+ * debugging in non-debug mode a bit easier.
25112511 */
2512 -$wgResourceLoaderMinifyJSVerticalSpace = false;
 2512+$wgResourceLoaderMinifierStatementsOnOwnLine = false;
25132513
25142514 /**
 2515+ * Maximum line length when minifying JavaScript. This is not a hard maximum:
 2516+ * the minifier will try not to produce lines longer than this, but may be
 2517+ * forced to do so in certain cases.
 2518+ */
 2519+$wgResourceLoaderMinifierMaxLineLength = 1000;
 2520+
 2521+/**
25152522 * Whether to include the mediawiki.legacy JS library (old wikibits.js), and its
25162523 * dependencies
25172524 */

Follow-up revisions

RevisionCommit summaryAuthorDate
r83934Followup r83891: don't insert a newline before ++ or -- . Patch by Paul Coppe...catrope18:04, 14 March 2011
r846131.17wmf1: MFT r81692, r82468, r83814, r83885, r83891, r83897, r83902, r83903,...catrope17:42, 23 March 2011
r85434MFT: r83885, r83891, r83897, r83902, r83903, r83934, r83965, r83979, r83988, ...demon13:38, 5 April 2011
r103865* (bug 32548) fix minification bug when numeric literal with exponent was spl...brion23:16, 21 November 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r83885(bug 27528) Incorporate Paul Copperman's minifiercatrope11:44, 14 March 2011

Status & tagging log