r90928 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90927‎ | r90928 | r90929 >
Date:01:09, 28 June 2011
Author:aaron
Status:ok
Tags:
Comment:
* Added truncate() & truncateHTML() tests
* Some fixes/changes to truncateHTML() based on tests
** Something like "<span>hello</span>" ends up as "<span>...</span>" instead of just "..." for relevant cases)
** If we get something like "<span></span" in, just return it back instead of ""
* Renamed $dispLength -> $dispLen in truncateHTML()
Modified paths:
  • /trunk/phase3/languages/Language.php (modified) (history)
  • /trunk/phase3/tests/phpunit/languages/LanguageTest.php (modified) (history)

Diff [purge]

Index: trunk/phase3/tests/phpunit/languages/LanguageTest.php
@@ -112,7 +112,109 @@
113113 );
114114 }
115115
 116+ function testTruncate() {
 117+ $this->assertEquals(
 118+ "XXX",
 119+ $this->lang->truncate( "1234567890", 0, 'XXX' ),
 120+ 'truncate prefix, len 0, small ellipsis'
 121+ );
 122+
 123+ $this->assertEquals(
 124+ "12345XXX",
 125+ $this->lang->truncate( "1234567890", 8, 'XXX' ),
 126+ 'truncate prefix, small ellipsis'
 127+ );
 128+
 129+ $this->assertEquals(
 130+ "123456789",
 131+ $this->lang->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
 132+ 'truncate prefix, large ellipsis'
 133+ );
 134+
 135+ $this->assertEquals(
 136+ "XXX67890",
 137+ $this->lang->truncate( "1234567890", -8, 'XXX' ),
 138+ 'truncate suffix, small ellipsis'
 139+ );
 140+
 141+ $this->assertEquals(
 142+ "123456789",
 143+ $this->lang->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
 144+ 'truncate suffix, large ellipsis'
 145+ );
 146+ }
 147+
116148 /**
 149+ * @dataProvider provideHTMLTruncateData()
 150+ */
 151+ function testTruncateHTML( $len, $ellipsis, $input, $expected ) {
 152+ // Actual HTML...
 153+ $this->assertEquals(
 154+ $expected,
 155+ $this->lang->truncateHTML( $input, $len, $ellipsis )
 156+ );
 157+ }
 158+
 159+ /**
 160+ * Array format is ($len, $ellipsis, $input, $expected)
 161+ */
 162+ function provideHTMLTruncateData() {
 163+ return array(
 164+ array( 0, 'XXX', "1234567890", "XXX" ),
 165+ array( 8, 'XXX', "1234567890", "12345XXX" ),
 166+ array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ),
 167+ array( 2, '***',
 168+ '<p><span style="font-weight:bold;"></span></p>',
 169+ '<p><span style="font-weight:bold;"></span></p>',
 170+ ),
 171+ array( 2, '***',
 172+ '<p><span style="font-weight:bold;">123456789</span></p>',
 173+ '<p><span style="font-weight:bold;">***</span></p>',
 174+ ),
 175+ array( 2, '***',
 176+ '<p><span style="font-weight:bold;">&nbsp;23456789</span></p>',
 177+ '<p><span style="font-weight:bold;">***</span></p>',
 178+ ),
 179+ array( 3, '***',
 180+ '<p><span style="font-weight:bold;">123456789</span></p>',
 181+ '<p><span style="font-weight:bold;">***</span></p>',
 182+ ),
 183+ array( 4, '***',
 184+ '<p><span style="font-weight:bold;">123456789</span></p>',
 185+ '<p><span style="font-weight:bold;">1***</span></p>',
 186+ ),
 187+ array( 5, '***',
 188+ '<tt><span style="font-weight:bold;">123456789</span></tt>',
 189+ '<tt><span style="font-weight:bold;">12***</span></tt>',
 190+ ),
 191+ array( 6, '***',
 192+ '<p><a href="www.mediawiki.org">123456789</a></p>',
 193+ '<p><a href="www.mediawiki.org">123***</a></p>',
 194+ ),
 195+ array( 6, '***',
 196+ '<p><a href="www.mediawiki.org">12&nbsp;456789</a></p>',
 197+ '<p><a href="www.mediawiki.org">12&nbsp;***</a></p>',
 198+ ),
 199+ array( 7, '***',
 200+ '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
 201+ '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
 202+ ),
 203+ array( 8, '***',
 204+ '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
 205+ '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
 206+ ),
 207+ array( 9, '***',
 208+ '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
 209+ '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
 210+ ),
 211+ array( 10, '***',
 212+ '<p><font style="font-weight:bold;">123456789</font></p>',
 213+ '<p><font style="font-weight:bold;">123456789</font></p>',
 214+ ),
 215+ );
 216+ }
 217+
 218+ /**
117219 * Test Language::isValidBuiltInCode()
118220 * @dataProvider provideLanguageCodes
119221 */
Index: trunk/phase3/languages/Language.php
@@ -2770,31 +2770,33 @@
27712771 return $text; // string short enough even *with* HTML (short-circuit)
27722772 }
27732773
2774 - $displayLen = 0; // innerHTML legth so far
 2774+ $dispLen = 0; // innerHTML legth so far
27752775 $testingEllipsis = false; // checking if ellipses will make string longer/equal?
27762776 $tagType = 0; // 0-open, 1-close
27772777 $bracketState = 0; // 1-tag start, 2-tag name, 0-neither
27782778 $entityState = 0; // 0-not entity, 1-entity
2779 - $tag = $ret = $pRet = ''; // accumulated tag name, accumulated result string
 2779+ $tag = $ret = ''; // accumulated tag name, accumulated result string
27802780 $openTags = array(); // open tag stack
2781 - $pOpenTags = array();
 2781+ $maybeState = null; // possible truncation state
27822782
27832783 $textLen = strlen( $text );
27842784 $neLength = max( 0, $length - strlen( $ellipsis ) ); // non-ellipsis len if truncated
27852785 for ( $pos = 0; true; ++$pos ) {
27862786 # Consider truncation once the display length has reached the maximim.
 2787+ # We check if $dispLen > 0 to grab tags for the $neLength = 0 case.
27872788 # Check that we're not in the middle of a bracket/entity...
2788 - if ( $displayLen >= $neLength && $bracketState == 0 && $entityState == 0 ) {
 2789+ if ( $dispLen && $dispLen >= $neLength && $bracketState == 0 && !$entityState ) {
27892790 if ( !$testingEllipsis ) {
27902791 $testingEllipsis = true;
27912792 # Save where we are; we will truncate here unless there turn out to
27922793 # be so few remaining characters that truncation is not necessary.
2793 - $pOpenTags = $openTags; // save state
2794 - $pRet = $ret; // save state
2795 - } elseif ( $displayLen > $length && $displayLen > strlen( $ellipsis ) ) {
 2794+ if ( !$maybeState ) { // already saved? ($neLength = 0 case)
 2795+ $maybeState = array( $ret, $openTags ); // save state
 2796+ }
 2797+ } elseif ( $dispLen > $length && $dispLen > strlen( $ellipsis ) ) {
27962798 # String in fact does need truncation, the truncation point was OK.
2797 - $openTags = $pOpenTags; // reload state
2798 - $ret = $this->removeBadCharLast( $pRet ); // reload state, multi-byte char fix
 2799+ list( $ret, $openTags ) = $maybeState; // reload state
 2800+ $ret = $this->removeBadCharLast( $ret ); // multi-byte char fix
27992801 $ret .= $ellipsis; // add ellipsis
28002802 break;
28012803 }
@@ -2832,25 +2834,27 @@
28332835 if ( $entityState ) {
28342836 if ( $ch == ';' ) {
28352837 $entityState = 0;
2836 - $displayLen++; // entity is one displayed char
 2838+ $dispLen++; // entity is one displayed char
28372839 }
28382840 } else {
 2841+ if ( $neLength == 0 && !$maybeState ) {
 2842+ // Save state without $ch. We want to *hit* the first
 2843+ // display char (to get tags) but not *use* it if truncating.
 2844+ $maybeState = array( substr( $ret, 0, -1 ), $openTags );
 2845+ }
28392846 if ( $ch == '&' ) {
28402847 $entityState = 1; // entity found, (e.g. "&#160;")
28412848 } else {
2842 - $displayLen++; // this char is displayed
 2849+ $dispLen++; // this char is displayed
28432850 // Add the next $max display text chars after this in one swoop...
2844 - $max = ( $testingEllipsis ? $length : $neLength ) - $displayLen;
 2851+ $max = ( $testingEllipsis ? $length : $neLength ) - $dispLen;
28452852 $skipped = $this->truncate_skip( $ret, $text, "<>&", $pos + 1, $max );
2846 - $displayLen += $skipped;
 2853+ $dispLen += $skipped;
28472854 $pos += $skipped;
28482855 }
28492856 }
28502857 }
28512858 }
2852 - if ( $displayLen == 0 ) {
2853 - return ''; // no text shown, nothing to format
2854 - }
28552859 // Close the last tag if left unclosed by bad HTML
28562860 $this->truncate_endBracket( $tag, $text[$textLen - 1], $tagType, $openTags );
28572861 while ( count( $openTags ) > 0 ) {

Sign-offs

UserFlagDate
Werdnainspected18:26, 15 July 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r84660(follow-up 79778) Make $wgLang->truncate function consider the length of the ...bawolff02:54, 24 March 2011
r84693* Follow-up for r84660:...aaron18:39, 24 March 2011

Status & tagging log