Merge "RCLFilters: make target and to/from parameters sticky again"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 19 Dec 2017 12:34:59 +0000 (12:34 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 19 Dec 2017 12:34:59 +0000 (12:34 +0000)
24 files changed:
includes/HistoryBlob.php
includes/Message.php
includes/cache/localisation/LCStoreStaticArray.php
includes/clientpool/SquidPurgeClient.php
includes/import/WikiImporter.php
includes/libs/MWMessagePack.php
includes/libs/mime/XmlTypeCheck.php
includes/media/Bitmap.php
includes/media/XCF.php
includes/page/WikiPage.php
includes/parser/BlockLevelPass.php
includes/parser/Parser.php
includes/parser/Preprocessor_Hash.php
includes/search/SearchEngine.php
includes/search/SearchMySQL.php
includes/skins/BaseTemplate.php
includes/tidy/Balancer.php
includes/utils/AutoloadGenerator.php
includes/utils/AvroValidator.php
languages/Language.php
languages/classes/LanguageGa.php
languages/classes/LanguageLa.php
tests/parser/ParserTestRunner.php
tests/parser/TestFileEditor.php

index 14d22ec..5193168 100644 (file)
@@ -560,26 +560,26 @@ class DiffHistoryBlob implements HistoryBlob {
                        $op = $x['op'];
                        ++$p;
                        switch ( $op ) {
-                       case self::XDL_BDOP_INS:
-                               $x = unpack( 'Csize', substr( $diff, $p, 1 ) );
-                               $p++;
-                               $out .= substr( $diff, $p, $x['size'] );
-                               $p += $x['size'];
-                               break;
-                       case self::XDL_BDOP_INSB:
-                               $x = unpack( 'Vcsize', substr( $diff, $p, 4 ) );
-                               $p += 4;
-                               $out .= substr( $diff, $p, $x['csize'] );
-                               $p += $x['csize'];
-                               break;
-                       case self::XDL_BDOP_CPY:
-                               $x = unpack( 'Voff/Vcsize', substr( $diff, $p, 8 ) );
-                               $p += 8;
-                               $out .= substr( $base, $x['off'], $x['csize'] );
-                               break;
-                       default:
-                               wfDebug( __METHOD__ . ": invalid op\n" );
-                               return false;
+                               case self::XDL_BDOP_INS:
+                                       $x = unpack( 'Csize', substr( $diff, $p, 1 ) );
+                                       $p++;
+                                       $out .= substr( $diff, $p, $x['size'] );
+                                       $p += $x['size'];
+                                       break;
+                               case self::XDL_BDOP_INSB:
+                                       $x = unpack( 'Vcsize', substr( $diff, $p, 4 ) );
+                                       $p += 4;
+                                       $out .= substr( $diff, $p, $x['csize'] );
+                                       $p += $x['csize'];
+                                       break;
+                               case self::XDL_BDOP_CPY:
+                                       $x = unpack( 'Voff/Vcsize', substr( $diff, $p, 8 ) );
+                                       $p += 8;
+                                       $out .= substr( $base, $x['off'], $x['csize'] );
+                                       break;
+                               default:
+                                       wfDebug( __METHOD__ . ": invalid op\n" );
+                                       return false;
                        }
                }
                return $out;
index 16ae839..e55eaaf 100644 (file)
@@ -1308,16 +1308,15 @@ class Message implements MessageSpecifier, Serializable {
         */
        protected function formatPlaintext( $plaintext, $format ) {
                switch ( $format ) {
-               case self::FORMAT_TEXT:
-               case self::FORMAT_PLAIN:
-                       return $plaintext;
-
-               case self::FORMAT_PARSE:
-               case self::FORMAT_BLOCK_PARSE:
-               case self::FORMAT_ESCAPED:
-               default:
-                       return htmlspecialchars( $plaintext, ENT_QUOTES );
-
+                       case self::FORMAT_TEXT:
+                       case self::FORMAT_PLAIN:
+                               return $plaintext;
+
+                       case self::FORMAT_PARSE:
+                       case self::FORMAT_BLOCK_PARSE:
+                       case self::FORMAT_ESCAPED:
+                       default:
+                               return htmlspecialchars( $plaintext, ENT_QUOTES );
                }
        }
 
index 1e20082..602c0ac 100644 (file)
@@ -97,17 +97,17 @@ class LCStoreStaticArray implements LCStore {
                $data = $encoded[1];
 
                switch ( $type ) {
-               case 'v':
-                       return $data;
-               case 's':
-                       return unserialize( $data );
-               case 'a':
-                       return array_map( function ( $v ) {
-                               return LCStoreStaticArray::decode( $v );
-                       }, $data );
-               default:
-                       throw new RuntimeException(
-                               'Unable to decode ' . var_export( $encoded, true ) );
+                       case 'v':
+                               return $data;
+                       case 's':
+                               return unserialize( $data );
+                       case 'a':
+                               return array_map( function ( $v ) {
+                                       return LCStoreStaticArray::decode( $v );
+                               }, $data );
+                       default:
+                               throw new RuntimeException(
+                                       'Unable to decode ' . var_export( $encoded, true ) );
                }
        }
 
index f454bd4..be802f9 100644 (file)
@@ -304,40 +304,40 @@ class SquidPurgeClient {
         */
        protected function processReadBuffer() {
                switch ( $this->readState ) {
-               case 'idle':
-                       return 'done';
-               case 'status':
-               case 'header':
-                       $lines = explode( "\r\n", $this->readBuffer, 2 );
-                       if ( count( $lines ) < 2 ) {
+                       case 'idle':
                                return 'done';
-                       }
-                       if ( $this->readState == 'status' ) {
-                               $this->processStatusLine( $lines[0] );
-                       } else { // header
-                               $this->processHeaderLine( $lines[0] );
-                       }
-                       $this->readBuffer = $lines[1];
-                       return 'continue';
-               case 'body':
-                       if ( $this->bodyRemaining !== null ) {
-                               if ( $this->bodyRemaining > strlen( $this->readBuffer ) ) {
-                                       $this->bodyRemaining -= strlen( $this->readBuffer );
-                                       $this->readBuffer = '';
+                       case 'status':
+                       case 'header':
+                               $lines = explode( "\r\n", $this->readBuffer, 2 );
+                               if ( count( $lines ) < 2 ) {
                                        return 'done';
+                               }
+                               if ( $this->readState == 'status' ) {
+                                       $this->processStatusLine( $lines[0] );
+                               } else { // header
+                                       $this->processHeaderLine( $lines[0] );
+                               }
+                               $this->readBuffer = $lines[1];
+                               return 'continue';
+                       case 'body':
+                               if ( $this->bodyRemaining !== null ) {
+                                       if ( $this->bodyRemaining > strlen( $this->readBuffer ) ) {
+                                               $this->bodyRemaining -= strlen( $this->readBuffer );
+                                               $this->readBuffer = '';
+                                               return 'done';
+                                       } else {
+                                               $this->readBuffer = substr( $this->readBuffer, $this->bodyRemaining );
+                                               $this->bodyRemaining = 0;
+                                               $this->nextRequest();
+                                               return 'continue';
+                                       }
                                } else {
-                                       $this->readBuffer = substr( $this->readBuffer, $this->bodyRemaining );
-                                       $this->bodyRemaining = 0;
-                                       $this->nextRequest();
-                                       return 'continue';
+                                       // No content length, read all data to EOF
+                                       $this->readBuffer = '';
+                                       return 'done';
                                }
-                       } else {
-                               // No content length, read all data to EOF
-                               $this->readBuffer = '';
-                               return 'done';
-                       }
-               default:
-                       throw new MWException( __METHOD__ . ': unexpected state' );
+                       default:
+                               throw new MWException( __METHOD__ . ': unexpected state' );
                }
        }
 
index 1424f33..28f3f82 100644 (file)
@@ -543,13 +543,13 @@ class WikiImporter {
                $buffer = "";
                while ( $this->reader->read() ) {
                        switch ( $this->reader->nodeType ) {
-                       case XMLReader::TEXT:
-                       case XMLReader::CDATA:
-                       case XMLReader::SIGNIFICANT_WHITESPACE:
-                               $buffer .= $this->reader->value;
-                               break;
-                       case XMLReader::END_ELEMENT:
-                               return $buffer;
+                               case XMLReader::TEXT:
+                               case XMLReader::CDATA:
+                               case XMLReader::SIGNIFICANT_WHITESPACE:
+                                       $buffer .= $this->reader->value;
+                                       break;
+                               case XMLReader::END_ELEMENT:
+                                       return $buffer;
                        }
                }
 
index a9da366..be7e93d 100644 (file)
@@ -53,137 +53,137 @@ class MWMessagePack {
                }
 
                switch ( gettype( $value ) ) {
-               case 'NULL':
-                       return "\xC0";
+                       case 'NULL':
+                               return "\xC0";
 
-               case 'boolean':
-                       return $value ? "\xC3" : "\xC2";
+                       case 'boolean':
+                               return $value ? "\xC3" : "\xC2";
 
-               case 'double':
-               case 'float':
-                       return self::$bigendian
-                               ? "\xCB" . pack( 'd', $value )
-                               : "\xCB" . strrev( pack( 'd', $value ) );
+                       case 'double':
+                       case 'float':
+                               return self::$bigendian
+                                       ? "\xCB" . pack( 'd', $value )
+                                       : "\xCB" . strrev( pack( 'd', $value ) );
 
-               case 'string':
-                       $length = strlen( $value );
-                       if ( $length < 32 ) {
-                               return pack( 'Ca*', 0xA0 | $length, $value );
-                       } elseif ( $length <= 0xFFFF ) {
-                               return pack( 'Cna*', 0xDA, $length, $value );
-                       } elseif ( $length <= 0xFFFFFFFF ) {
-                               return pack( 'CNa*', 0xDB, $length, $value );
-                       }
-                       throw new InvalidArgumentException( __METHOD__
-                               . ": string too long (length: $length; max: 4294967295)" );
-
-               case 'integer':
-                       if ( $value >= 0 ) {
-                               if ( $value <= 0x7F ) {
-                                       // positive fixnum
-                                       return chr( $value );
-                               }
-                               if ( $value <= 0xFF ) {
-                                       // uint8
-                                       return pack( 'CC', 0xCC, $value );
-                               }
-                               if ( $value <= 0xFFFF ) {
-                                       // uint16
-                                       return pack( 'Cn', 0xCD, $value );
-                               }
-                               if ( $value <= 0xFFFFFFFF ) {
-                                       // uint32
-                                       return pack( 'CN', 0xCE, $value );
-                               }
-                               if ( $value <= 0xFFFFFFFFFFFFFFFF ) {
-                                       // uint64
-                                       $hi = ( $value & 0xFFFFFFFF00000000 ) >> 32;
-                                       $lo = $value & 0xFFFFFFFF;
-                                       return self::$bigendian
-                                               ? pack( 'CNN', 0xCF, $lo, $hi )
-                                               : pack( 'CNN', 0xCF, $hi, $lo );
-                               }
-                       } else {
-                               if ( $value >= -32 ) {
-                                       // negative fixnum
-                                       return pack( 'c', $value );
-                               }
-                               if ( $value >= -0x80 ) {
-                                       // int8
-                                       return pack( 'Cc', 0xD0, $value );
-                               }
-                               if ( $value >= -0x8000 ) {
-                                       // int16
-                                       $p = pack( 's', $value );
-                                       return self::$bigendian
-                                               ? pack( 'Ca2', 0xD1, $p )
-                                               : pack( 'Ca2', 0xD1, strrev( $p ) );
-                               }
-                               if ( $value >= -0x80000000 ) {
-                                       // int32
-                                       $p = pack( 'l', $value );
-                                       return self::$bigendian
-                                               ? pack( 'Ca4', 0xD2, $p )
-                                               : pack( 'Ca4', 0xD2, strrev( $p ) );
-                               }
-                               if ( $value >= -0x8000000000000000 ) {
-                                       // int64
-                                       // pack() does not support 64-bit ints either so pack into two 32-bits
-                                       $p1 = pack( 'l', $value & 0xFFFFFFFF );
-                                       $p2 = pack( 'l', ( $value >> 32 ) & 0xFFFFFFFF );
-                                       return self::$bigendian
-                                               ? pack( 'Ca4a4', 0xD3, $p1, $p2 )
-                                               : pack( 'Ca4a4', 0xD3, strrev( $p2 ), strrev( $p1 ) );
+                       case 'string':
+                               $length = strlen( $value );
+                               if ( $length < 32 ) {
+                                       return pack( 'Ca*', 0xA0 | $length, $value );
+                               } elseif ( $length <= 0xFFFF ) {
+                                       return pack( 'Cna*', 0xDA, $length, $value );
+                               } elseif ( $length <= 0xFFFFFFFF ) {
+                                       return pack( 'CNa*', 0xDB, $length, $value );
                                }
-                       }
-                       throw new InvalidArgumentException( __METHOD__ . ": invalid integer '$value'" );
-
-               case 'array':
-                       $buffer = '';
-                       $length = count( $value );
-                       if ( $length > 0xFFFFFFFF ) {
                                throw new InvalidArgumentException( __METHOD__
-                                       . ": array too long (length: $length, max: 4294967295)" );
-                       }
+                                       . ": string too long (length: $length; max: 4294967295)" );
 
-                       $index = 0;
-                       foreach ( $value as $k => $v ) {
-                               if ( $index !== $k || $index === $length ) {
-                                       break;
+                       case 'integer':
+                               if ( $value >= 0 ) {
+                                       if ( $value <= 0x7F ) {
+                                               // positive fixnum
+                                               return chr( $value );
+                                       }
+                                       if ( $value <= 0xFF ) {
+                                               // uint8
+                                               return pack( 'CC', 0xCC, $value );
+                                       }
+                                       if ( $value <= 0xFFFF ) {
+                                               // uint16
+                                               return pack( 'Cn', 0xCD, $value );
+                                       }
+                                       if ( $value <= 0xFFFFFFFF ) {
+                                               // uint32
+                                               return pack( 'CN', 0xCE, $value );
+                                       }
+                                       if ( $value <= 0xFFFFFFFFFFFFFFFF ) {
+                                               // uint64
+                                               $hi = ( $value & 0xFFFFFFFF00000000 ) >> 32;
+                                               $lo = $value & 0xFFFFFFFF;
+                                               return self::$bigendian
+                                                       ? pack( 'CNN', 0xCF, $lo, $hi )
+                                                       : pack( 'CNN', 0xCF, $hi, $lo );
+                                       }
                                } else {
-                                       $index++;
+                                       if ( $value >= -32 ) {
+                                               // negative fixnum
+                                               return pack( 'c', $value );
+                                       }
+                                       if ( $value >= -0x80 ) {
+                                               // int8
+                                               return pack( 'Cc', 0xD0, $value );
+                                       }
+                                       if ( $value >= -0x8000 ) {
+                                               // int16
+                                               $p = pack( 's', $value );
+                                               return self::$bigendian
+                                                       ? pack( 'Ca2', 0xD1, $p )
+                                                       : pack( 'Ca2', 0xD1, strrev( $p ) );
+                                       }
+                                       if ( $value >= -0x80000000 ) {
+                                               // int32
+                                               $p = pack( 'l', $value );
+                                               return self::$bigendian
+                                                       ? pack( 'Ca4', 0xD2, $p )
+                                                       : pack( 'Ca4', 0xD2, strrev( $p ) );
+                                       }
+                                       if ( $value >= -0x8000000000000000 ) {
+                                               // int64
+                                               // pack() does not support 64-bit ints either so pack into two 32-bits
+                                               $p1 = pack( 'l', $value & 0xFFFFFFFF );
+                                               $p2 = pack( 'l', ( $value >> 32 ) & 0xFFFFFFFF );
+                                               return self::$bigendian
+                                                       ? pack( 'Ca4a4', 0xD3, $p1, $p2 )
+                                                       : pack( 'Ca4a4', 0xD3, strrev( $p2 ), strrev( $p1 ) );
+                                       }
                                }
-                       }
-                       $associative = $index !== $length;
+                               throw new InvalidArgumentException( __METHOD__ . ": invalid integer '$value'" );
 
-                       if ( $associative ) {
-                               if ( $length < 16 ) {
-                                       $buffer .= pack( 'C', 0x80 | $length );
-                               } elseif ( $length <= 0xFFFF ) {
-                                       $buffer .= pack( 'Cn', 0xDE, $length );
-                               } else {
-                                       $buffer .= pack( 'CN', 0xDF, $length );
+                       case 'array':
+                               $buffer = '';
+                               $length = count( $value );
+                               if ( $length > 0xFFFFFFFF ) {
+                                       throw new InvalidArgumentException( __METHOD__
+                                               . ": array too long (length: $length, max: 4294967295)" );
                                }
+
+                               $index = 0;
                                foreach ( $value as $k => $v ) {
-                                       $buffer .= self::pack( $k );
-                                       $buffer .= self::pack( $v );
+                                       if ( $index !== $k || $index === $length ) {
+                                               break;
+                                       } else {
+                                               $index++;
+                                       }
                                }
-                       } else {
-                               if ( $length < 16 ) {
-                                       $buffer .= pack( 'C', 0x90 | $length );
-                               } elseif ( $length <= 0xFFFF ) {
-                                       $buffer .= pack( 'Cn', 0xDC, $length );
+                               $associative = $index !== $length;
+
+                               if ( $associative ) {
+                                       if ( $length < 16 ) {
+                                               $buffer .= pack( 'C', 0x80 | $length );
+                                       } elseif ( $length <= 0xFFFF ) {
+                                               $buffer .= pack( 'Cn', 0xDE, $length );
+                                       } else {
+                                               $buffer .= pack( 'CN', 0xDF, $length );
+                                       }
+                                       foreach ( $value as $k => $v ) {
+                                               $buffer .= self::pack( $k );
+                                               $buffer .= self::pack( $v );
+                                       }
                                } else {
-                                       $buffer .= pack( 'CN', 0xDD, $length );
-                               }
-                               foreach ( $value as $v ) {
-                                       $buffer .= self::pack( $v );
+                                       if ( $length < 16 ) {
+                                               $buffer .= pack( 'C', 0x90 | $length );
+                                       } elseif ( $length <= 0xFFFF ) {
+                                               $buffer .= pack( 'Cn', 0xDC, $length );
+                                       } else {
+                                               $buffer .= pack( 'CN', 0xDD, $length );
+                                       }
+                                       foreach ( $value as $v ) {
+                                               $buffer .= self::pack( $v );
+                                       }
                                }
-                       }
-                       return $buffer;
+                               return $buffer;
 
-               default:
-                       throw new InvalidArgumentException( __METHOD__ . ': unsupported type ' . gettype( $value ) );
+                       default:
+                               throw new InvalidArgumentException( __METHOD__ . ': unsupported type ' . gettype( $value ) );
                }
        }
 }
index ea7f9a6..9761108 100644 (file)
@@ -479,23 +479,23 @@ class XmlTypeCheck {
                                continue;
                        }
                        switch ( $field ) {
-                       case 'typepublic':
-                       case 'typesystem':
-                               $parsed['type'] = $value;
-                               break;
-                       case 'pubquote':
-                       case 'pubapos':
-                               $parsed['publicid'] = $value;
-                               break;
-                       case 'pubsysquote':
-                       case 'pubsysapos':
-                       case 'sysquote':
-                       case 'sysapos':
-                               $parsed['systemid'] = $value;
-                               break;
-                       case 'internal':
-                               $parsed['internal'] = $value;
-                               break;
+                               case 'typepublic':
+                               case 'typesystem':
+                                       $parsed['type'] = $value;
+                                       break;
+                               case 'pubquote':
+                               case 'pubapos':
+                                       $parsed['publicid'] = $value;
+                                       break;
+                               case 'pubsysquote':
+                               case 'pubsysapos':
+                               case 'sysquote':
+                               case 'sysapos':
+                                       $parsed['systemid'] = $value;
+                                       break;
+                               case 'internal':
+                                       $parsed['internal'] = $value;
+                                       break;
                        }
                }
                return $parsed;
index ac39e6f..617a910 100644 (file)
@@ -112,14 +112,14 @@ class BitmapHandler extends TransformationalImageHandler {
         */
        protected function imageMagickSubsampling( $pixelFormat ) {
                switch ( $pixelFormat ) {
-               case 'yuv444':
-                       return [ '1x1', '1x1', '1x1' ];
-               case 'yuv422':
-                       return [ '2x1', '1x1', '1x1' ];
-               case 'yuv420':
-                       return [ '2x2', '1x1', '1x1' ];
-               default:
-                       throw new MWException( 'Invalid pixel format for JPEG output' );
+                       case 'yuv444':
+                               return [ '1x1', '1x1', '1x1' ];
+                       case 'yuv422':
+                               return [ '2x1', '1x1', '1x1' ];
+                       case 'yuv420':
+                               return [ '2x2', '1x1', '1x1' ];
+                       default:
+                               throw new MWException( 'Invalid pixel format for JPEG output' );
                }
        }
 
index c419524..3587eba 100644 (file)
@@ -162,18 +162,17 @@ class XCFHandler extends BitmapHandler {
                        // Unclear from base media type if it has an alpha layer,
                        // so just assume that it does since it "potentially" could.
                        switch ( $header['base_type'] ) {
-                       case 0:
-                               $metadata['colorType'] = 'truecolour-alpha';
-                               break;
-                       case 1:
-                               $metadata['colorType'] = 'greyscale-alpha';
-                               break;
-                       case 2:
-                               $metadata['colorType'] = 'index-coloured';
-                               break;
-                       default:
-                               $metadata['colorType'] = 'unknown';
-
+                               case 0:
+                                       $metadata['colorType'] = 'truecolour-alpha';
+                                       break;
+                               case 1:
+                                       $metadata['colorType'] = 'greyscale-alpha';
+                                       break;
+                               case 2:
+                                       $metadata['colorType'] = 'index-coloured';
+                                       break;
+                               default:
+                                       $metadata['colorType'] = 'unknown';
                        }
                } else {
                        // Marker to prevent repeated attempted extraction
index 7498ca5..c37566b 100644 (file)
@@ -195,15 +195,15 @@ class WikiPage implements Page, IDBAccessObject {
         */
        private static function convertSelectType( $type ) {
                switch ( $type ) {
-               case 'fromdb':
-                       return self::READ_NORMAL;
-               case 'fromdbmaster':
-                       return self::READ_LATEST;
-               case 'forupdate':
-                       return self::READ_LOCKING;
-               default:
-                       // It may already be an integer or whatever else
-                       return $type;
+                       case 'fromdb':
+                               return self::READ_NORMAL;
+                       case 'fromdbmaster':
+                               return self::READ_LATEST;
+                       case 'forupdate':
+                               return self::READ_LOCKING;
+                       default:
+                               // It may already be an integer or whatever else
+                               return $type;
                }
        }
 
index fab9ab7..761d5be 100644 (file)
@@ -417,130 +417,130 @@ class BlockLevelPass {
                        $c = $str[$i];
 
                        switch ( $state ) {
-                       case self::COLON_STATE_TEXT:
-                               switch ( $c ) {
-                               case "<":
-                                       # Could be either a <start> tag or an </end> tag
-                                       $state = self::COLON_STATE_TAGSTART;
-                                       break;
-                               case ":":
-                                       if ( $ltLevel === 0 ) {
-                                               # We found it!
-                                               $before = substr( $str, 0, $i );
-                                               $after = substr( $str, $i + 1 );
-                                               return $i;
+                               case self::COLON_STATE_TEXT:
+                                       switch ( $c ) {
+                                               case "<":
+                                                       # Could be either a <start> tag or an </end> tag
+                                                       $state = self::COLON_STATE_TAGSTART;
+                                                       break;
+                                               case ":":
+                                                       if ( $ltLevel === 0 ) {
+                                                               # We found it!
+                                                               $before = substr( $str, 0, $i );
+                                                               $after = substr( $str, $i + 1 );
+                                                               return $i;
+                                                       }
+                                                       # Embedded in a tag; don't break it.
+                                                       break;
+                                               default:
+                                                       # Skip ahead looking for something interesting
+                                                       if ( !preg_match( '/:|<|-\{/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
+                                                               # Nothing else interesting
+                                                               return false;
+                                                       }
+                                                       if ( $m[0][0] === '-{' ) {
+                                                               $state = self::COLON_STATE_LC;
+                                                               $lcLevel++;
+                                                               $i = $m[0][1] + 1;
+                                                       } else {
+                                                               # Skip ahead to next interesting character.
+                                                               $i = $m[0][1] - 1;
+                                                       }
+                                                       break;
                                        }
-                                       # Embedded in a tag; don't break it.
                                        break;
-                               default:
-                                       # Skip ahead looking for something interesting
-                                       if ( !preg_match( '/:|<|-\{/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
-                                               # Nothing else interesting
-                                               return false;
-                                       }
-                                       if ( $m[0][0] === '-{' ) {
-                                               $state = self::COLON_STATE_LC;
+                               case self::COLON_STATE_LC:
+                                       # In language converter markup -{ ... }-
+                                       if ( !preg_match( '/-\{|\}-/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
+                                               # Nothing else interesting to find; abort!
+                                               # We're nested in language converter markup, but there
+                                               # are no close tags left.  Abort!
+                                               break 2;
+                                       } elseif ( $m[0][0] === '-{' ) {
+                                               $i = $m[0][1] + 1;
                                                $lcLevel++;
+                                       } elseif ( $m[0][0] === '}-' ) {
                                                $i = $m[0][1] + 1;
-                                       } else {
-                                               # Skip ahead to next interesting character.
-                                               $i = $m[0][1] - 1;
+                                               $lcLevel--;
+                                               if ( $lcLevel === 0 ) {
+                                                       $state = self::COLON_STATE_TEXT;
+                                               }
                                        }
                                        break;
-                               }
-                               break;
-                       case self::COLON_STATE_LC:
-                               # In language converter markup -{ ... }-
-                               if ( !preg_match( '/-\{|\}-/', $str, $m, PREG_OFFSET_CAPTURE, $i ) ) {
-                                       # Nothing else interesting to find; abort!
-                                       # We're nested in language converter markup, but there
-                                       # are no close tags left.  Abort!
-                                       break 2;
-                               } elseif ( $m[0][0] === '-{' ) {
-                                       $i = $m[0][1] + 1;
-                                       $lcLevel++;
-                               } elseif ( $m[0][0] === '}-' ) {
-                                       $i = $m[0][1] + 1;
-                                       $lcLevel--;
-                                       if ( $lcLevel === 0 ) {
-                                               $state = self::COLON_STATE_TEXT;
+                               case self::COLON_STATE_TAG:
+                                       # In a <tag>
+                                       switch ( $c ) {
+                                               case ">":
+                                                       $ltLevel++;
+                                                       $state = self::COLON_STATE_TEXT;
+                                                       break;
+                                               case "/":
+                                                       # Slash may be followed by >?
+                                                       $state = self::COLON_STATE_TAGSLASH;
+                                                       break;
+                                               default:
+                                                       # ignore
                                        }
-                               }
-                               break;
-                       case self::COLON_STATE_TAG:
-                               # In a <tag>
-                               switch ( $c ) {
-                               case ">":
-                                       $ltLevel++;
-                                       $state = self::COLON_STATE_TEXT;
                                        break;
-                               case "/":
-                                       # Slash may be followed by >?
-                                       $state = self::COLON_STATE_TAGSLASH;
+                               case self::COLON_STATE_TAGSTART:
+                                       switch ( $c ) {
+                                               case "/":
+                                                       $state = self::COLON_STATE_CLOSETAG;
+                                                       break;
+                                               case "!":
+                                                       $state = self::COLON_STATE_COMMENT;
+                                                       break;
+                                               case ">":
+                                                       # Illegal early close? This shouldn't happen D:
+                                                       $state = self::COLON_STATE_TEXT;
+                                                       break;
+                                               default:
+                                                       $state = self::COLON_STATE_TAG;
+                                       }
                                        break;
-                               default:
-                                       # ignore
-                               }
-                               break;
-                       case self::COLON_STATE_TAGSTART:
-                               switch ( $c ) {
-                               case "/":
-                                       $state = self::COLON_STATE_CLOSETAG;
+                               case self::COLON_STATE_CLOSETAG:
+                                       # In a </tag>
+                                       if ( $c === ">" ) {
+                                               if ( $ltLevel > 0 ) {
+                                                       $ltLevel--;
+                                               } else {
+                                                       # ignore the excess close tag, but keep looking for
+                                                       # colons. (This matches Parsoid behavior.)
+                                                       wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
+                                               }
+                                               $state = self::COLON_STATE_TEXT;
+                                       }
                                        break;
-                               case "!":
-                                       $state = self::COLON_STATE_COMMENT;
+                               case self::COLON_STATE_TAGSLASH:
+                                       if ( $c === ">" ) {
+                                               # Yes, a self-closed tag <blah/>
+                                               $state = self::COLON_STATE_TEXT;
+                                       } else {
+                                               # Probably we're jumping the gun, and this is an attribute
+                                               $state = self::COLON_STATE_TAG;
+                                       }
                                        break;
-                               case ">":
-                                       # Illegal early close? This shouldn't happen D:
-                                       $state = self::COLON_STATE_TEXT;
+                               case self::COLON_STATE_COMMENT:
+                                       if ( $c === "-" ) {
+                                               $state = self::COLON_STATE_COMMENTDASH;
+                                       }
                                        break;
-                               default:
-                                       $state = self::COLON_STATE_TAG;
-                               }
-                               break;
-                       case self::COLON_STATE_CLOSETAG:
-                               # In a </tag>
-                               if ( $c === ">" ) {
-                                       if ( $ltLevel > 0 ) {
-                                               $ltLevel--;
+                               case self::COLON_STATE_COMMENTDASH:
+                                       if ( $c === "-" ) {
+                                               $state = self::COLON_STATE_COMMENTDASHDASH;
                                        } else {
-                                               # ignore the excess close tag, but keep looking for
-                                               # colons. (This matches Parsoid behavior.)
-                                               wfDebug( __METHOD__ . ": Invalid input; too many close tags\n" );
+                                               $state = self::COLON_STATE_COMMENT;
                                        }
-                                       $state = self::COLON_STATE_TEXT;
-                               }
-                               break;
-                       case self::COLON_STATE_TAGSLASH:
-                               if ( $c === ">" ) {
-                                       # Yes, a self-closed tag <blah/>
-                                       $state = self::COLON_STATE_TEXT;
-                               } else {
-                                       # Probably we're jumping the gun, and this is an attribute
-                                       $state = self::COLON_STATE_TAG;
-                               }
-                               break;
-                       case self::COLON_STATE_COMMENT:
-                               if ( $c === "-" ) {
-                                       $state = self::COLON_STATE_COMMENTDASH;
-                               }
-                               break;
-                       case self::COLON_STATE_COMMENTDASH:
-                               if ( $c === "-" ) {
-                                       $state = self::COLON_STATE_COMMENTDASHDASH;
-                               } else {
-                                       $state = self::COLON_STATE_COMMENT;
-                               }
-                               break;
-                       case self::COLON_STATE_COMMENTDASHDASH:
-                               if ( $c === ">" ) {
-                                       $state = self::COLON_STATE_TEXT;
-                               } else {
-                                       $state = self::COLON_STATE_COMMENT;
-                               }
-                               break;
-                       default:
-                               throw new MWException( "State machine error in " . __METHOD__ );
+                                       break;
+                               case self::COLON_STATE_COMMENTDASHDASH:
+                                       if ( $c === ">" ) {
+                                               $state = self::COLON_STATE_TEXT;
+                                       } else {
+                                               $state = self::COLON_STATE_COMMENT;
+                                       }
+                                       break;
+                               default:
+                                       throw new MWException( "State machine error in " . __METHOD__ );
                        }
                }
                if ( $ltLevel > 0 || $lcLevel > 0 ) {
index 8986ddd..10a338e 100644 (file)
@@ -5022,40 +5022,40 @@ class Parser {
                                                $paramName = $paramMap[$magicName];
 
                                                switch ( $paramName ) {
-                                               case 'gallery-internal-alt':
-                                                       $alt = $this->stripAltText( $match, false );
-                                                       break;
-                                               case 'gallery-internal-link':
-                                                       $linkValue = strip_tags( $this->replaceLinkHoldersText( $match ) );
-                                                       $chars = self::EXT_LINK_URL_CLASS;
-                                                       $addr = self::EXT_LINK_ADDR;
-                                                       $prots = $this->mUrlProtocols;
-                                                       // check to see if link matches an absolute url, if not then it must be a wiki link.
-                                                       if ( preg_match( '/^-{R|(.*)}-$/', $linkValue ) ) {
-                                                               // Result of LanguageConverter::markNoConversion
-                                                               // invoked on an external link.
-                                                               $linkValue = substr( $linkValue, 4, -2 );
-                                                       }
-                                                       if ( preg_match( "/^($prots)$addr$chars*$/u", $linkValue ) ) {
-                                                               $link = $linkValue;
-                                                               $this->mOutput->addExternalLink( $link );
-                                                       } else {
-                                                               $localLinkTitle = Title::newFromText( $linkValue );
-                                                               if ( $localLinkTitle !== null ) {
-                                                                       $this->mOutput->addLink( $localLinkTitle );
-                                                                       $link = $localLinkTitle->getLinkURL();
+                                                       case 'gallery-internal-alt':
+                                                               $alt = $this->stripAltText( $match, false );
+                                                               break;
+                                                       case 'gallery-internal-link':
+                                                               $linkValue = strip_tags( $this->replaceLinkHoldersText( $match ) );
+                                                               $chars = self::EXT_LINK_URL_CLASS;
+                                                               $addr = self::EXT_LINK_ADDR;
+                                                               $prots = $this->mUrlProtocols;
+                                                               // check to see if link matches an absolute url, if not then it must be a wiki link.
+                                                               if ( preg_match( '/^-{R|(.*)}-$/', $linkValue ) ) {
+                                                                       // Result of LanguageConverter::markNoConversion
+                                                                       // invoked on an external link.
+                                                                       $linkValue = substr( $linkValue, 4, -2 );
+                                                               }
+                                                               if ( preg_match( "/^($prots)$addr$chars*$/u", $linkValue ) ) {
+                                                                       $link = $linkValue;
+                                                                       $this->mOutput->addExternalLink( $link );
+                                                               } else {
+                                                                       $localLinkTitle = Title::newFromText( $linkValue );
+                                                                       if ( $localLinkTitle !== null ) {
+                                                                               $this->mOutput->addLink( $localLinkTitle );
+                                                                               $link = $localLinkTitle->getLinkURL();
+                                                                       }
+                                                               }
+                                                               break;
+                                                       default:
+                                                               // Must be a handler specific parameter.
+                                                               if ( $handler->validateParam( $paramName, $match ) ) {
+                                                                       $handlerOptions[$paramName] = $match;
+                                                               } else {
+                                                                       // Guess not, consider it as caption.
+                                                                       wfDebug( "$parameterMatch failed parameter validation\n" );
+                                                                       $label = '|' . $parameterMatch;
                                                                }
-                                                       }
-                                                       break;
-                                               default:
-                                                       // Must be a handler specific parameter.
-                                                       if ( $handler->validateParam( $paramName, $match ) ) {
-                                                               $handlerOptions[$paramName] = $match;
-                                                       } else {
-                                                               // Guess not, consider it as caption.
-                                                               wfDebug( "$parameterMatch failed parameter validation\n" );
-                                                               $label = '|' . $parameterMatch;
-                                                       }
                                                }
 
                                        } else {
@@ -5217,52 +5217,52 @@ class Parser {
                                        } else {
                                                # Validate internal parameters
                                                switch ( $paramName ) {
-                                               case 'manualthumb':
-                                               case 'alt':
-                                               case 'class':
-                                                       # @todo FIXME: Possibly check validity here for
-                                                       # manualthumb? downstream behavior seems odd with
-                                                       # missing manual thumbs.
-                                                       $validated = true;
-                                                       $value = $this->stripAltText( $value, $holders );
-                                                       break;
-                                               case 'link':
-                                                       $chars = self::EXT_LINK_URL_CLASS;
-                                                       $addr = self::EXT_LINK_ADDR;
-                                                       $prots = $this->mUrlProtocols;
-                                                       if ( $value === '' ) {
-                                                               $paramName = 'no-link';
-                                                               $value = true;
+                                                       case 'manualthumb':
+                                                       case 'alt':
+                                                       case 'class':
+                                                               # @todo FIXME: Possibly check validity here for
+                                                               # manualthumb? downstream behavior seems odd with
+                                                               # missing manual thumbs.
                                                                $validated = true;
-                                                       } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
-                                                               if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
-                                                                       $paramName = 'link-url';
-                                                                       $this->mOutput->addExternalLink( $value );
-                                                                       if ( $this->mOptions->getExternalLinkTarget() ) {
-                                                                               $params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget();
-                                                                       }
-                                                                       $validated = true;
-                                                               }
-                                                       } else {
-                                                               $linkTitle = Title::newFromText( $value );
-                                                               if ( $linkTitle ) {
-                                                                       $paramName = 'link-title';
-                                                                       $value = $linkTitle;
-                                                                       $this->mOutput->addLink( $linkTitle );
+                                                               $value = $this->stripAltText( $value, $holders );
+                                                               break;
+                                                       case 'link':
+                                                               $chars = self::EXT_LINK_URL_CLASS;
+                                                               $addr = self::EXT_LINK_ADDR;
+                                                               $prots = $this->mUrlProtocols;
+                                                               if ( $value === '' ) {
+                                                                       $paramName = 'no-link';
+                                                                       $value = true;
                                                                        $validated = true;
+                                                               } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
+                                                                       if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
+                                                                               $paramName = 'link-url';
+                                                                               $this->mOutput->addExternalLink( $value );
+                                                                               if ( $this->mOptions->getExternalLinkTarget() ) {
+                                                                                       $params[$type]['link-target'] = $this->mOptions->getExternalLinkTarget();
+                                                                               }
+                                                                               $validated = true;
+                                                                       }
+                                                               } else {
+                                                                       $linkTitle = Title::newFromText( $value );
+                                                                       if ( $linkTitle ) {
+                                                                               $paramName = 'link-title';
+                                                                               $value = $linkTitle;
+                                                                               $this->mOutput->addLink( $linkTitle );
+                                                                               $validated = true;
+                                                                       }
                                                                }
-                                                       }
-                                                       break;
-                                               case 'frameless':
-                                               case 'framed':
-                                               case 'thumbnail':
-                                                       // use first appearing option, discard others.
-                                                       $validated = !$seenformat;
-                                                       $seenformat = true;
-                                                       break;
-                                               default:
-                                                       # Most other things appear to be empty or numeric...
-                                                       $validated = ( $value === false || is_numeric( trim( $value ) ) );
+                                                               break;
+                                                       case 'frameless':
+                                                       case 'framed':
+                                                       case 'thumbnail':
+                                                               // use first appearing option, discard others.
+                                                               $validated = !$seenformat;
+                                                               $seenformat = true;
+                                                               break;
+                                                       default:
+                                                               # Most other things appear to be empty or numeric...
+                                                               $validated = ( $value === false || is_numeric( trim( $value ) ) );
                                                }
                                        }
 
index 332f8e9..735c33a 100644 (file)
@@ -1922,18 +1922,18 @@ class PPNode_Hash_Tree implements PPNode {
                                continue;
                        }
                        switch ( $child[self::NAME] ) {
-                       case 'name':
-                               $bits['name'] = new self( $children, $i );
-                               break;
-                       case 'attr':
-                               $bits['attr'] = new self( $children, $i );
-                               break;
-                       case 'inner':
-                               $bits['inner'] = new self( $children, $i );
-                               break;
-                       case 'close':
-                               $bits['close'] = new self( $children, $i );
-                               break;
+                               case 'name':
+                                       $bits['name'] = new self( $children, $i );
+                                       break;
+                               case 'attr':
+                                       $bits['attr'] = new self( $children, $i );
+                                       break;
+                               case 'inner':
+                                       $bits['inner'] = new self( $children, $i );
+                                       break;
+                               case 'close':
+                                       $bits['close'] = new self( $children, $i );
+                                       break;
                        }
                }
                if ( !isset( $bits['name'] ) ) {
@@ -2001,15 +2001,15 @@ class PPNode_Hash_Tree implements PPNode {
                                continue;
                        }
                        switch ( $child[self::NAME] ) {
-                       case 'title':
-                               $bits['title'] = new self( $children, $i );
-                               break;
-                       case 'part':
-                               $parts[] = new self( $children, $i );
-                               break;
-                       case '@lineStart':
-                               $bits['lineStart'] = '1';
-                               break;
+                               case 'title':
+                                       $bits['title'] = new self( $children, $i );
+                                       break;
+                               case 'part':
+                                       $parts[] = new self( $children, $i );
+                                       break;
+                               case '@lineStart':
+                                       $bits['lineStart'] = '1';
+                                       break;
                        }
                }
                if ( !isset( $bits['title'] ) ) {
index 3c8fe60..4253193 100644 (file)
@@ -112,11 +112,11 @@ abstract class SearchEngine {
         */
        public function supports( $feature ) {
                switch ( $feature ) {
-               case 'search-update':
-                       return true;
-               case 'title-suffix-filter':
-               default:
-                       return false;
+                       case 'search-update':
+                               return true;
+                       case 'title-suffix-filter':
+                       default:
+                               return false;
                }
        }
 
index 77dcfe9..2810bce 100644 (file)
@@ -209,10 +209,10 @@ class SearchMySQL extends SearchDatabase {
 
        public function supports( $feature ) {
                switch ( $feature ) {
-               case 'title-suffix-filter':
-                       return true;
-               default:
-                       return parent::supports( $feature );
+                       case 'title-suffix-filter':
+                               return true;
+                       default:
+                               return parent::supports( $feature );
                }
        }
 
index 8d5ce10..f0b336a 100644 (file)
@@ -182,44 +182,44 @@ abstract class BaseTemplate extends QuickTemplate {
                                continue;
                        }
                        switch ( $boxName ) {
-                       case 'SEARCH':
-                               // Search is a special case, skins should custom implement this
-                               $boxes[$boxName] = [
-                                       'id' => 'p-search',
-                                       'header' => $this->getMsg( 'search' )->text(),
-                                       'generated' => false,
-                                       'content' => true,
-                               ];
-                               break;
-                       case 'TOOLBOX':
-                               $msgObj = $this->getMsg( 'toolbox' );
-                               $boxes[$boxName] = [
-                                       'id' => 'p-tb',
-                                       'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
-                                       'generated' => false,
-                                       'content' => $this->getToolbox(),
-                               ];
-                               break;
-                       case 'LANGUAGES':
-                               if ( $this->data['language_urls'] !== false ) {
-                                       $msgObj = $this->getMsg( 'otherlanguages' );
+                               case 'SEARCH':
+                                       // Search is a special case, skins should custom implement this
                                        $boxes[$boxName] = [
-                                               'id' => 'p-lang',
-                                               'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
+                                               'id' => 'p-search',
+                                               'header' => $this->getMsg( 'search' )->text(),
                                                'generated' => false,
-                                               'content' => $this->data['language_urls'] ?: [],
+                                               'content' => true,
                                        ];
-                               }
-                               break;
-                       default:
-                               $msgObj = $this->getMsg( $boxName );
-                               $boxes[$boxName] = [
-                                       'id' => "p-$boxName",
-                                       'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
-                                       'generated' => true,
-                                       'content' => $content,
-                               ];
-                               break;
+                                       break;
+                               case 'TOOLBOX':
+                                       $msgObj = $this->getMsg( 'toolbox' );
+                                       $boxes[$boxName] = [
+                                               'id' => 'p-tb',
+                                               'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
+                                               'generated' => false,
+                                               'content' => $this->getToolbox(),
+                                       ];
+                                       break;
+                               case 'LANGUAGES':
+                                       if ( $this->data['language_urls'] !== false ) {
+                                               $msgObj = $this->getMsg( 'otherlanguages' );
+                                               $boxes[$boxName] = [
+                                                       'id' => 'p-lang',
+                                                       'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
+                                                       'generated' => false,
+                                                       'content' => $this->data['language_urls'] ?: [],
+                                               ];
+                                       }
+                                       break;
+                               default:
+                                       $msgObj = $this->getMsg( $boxName );
+                                       $boxes[$boxName] = [
+                                               'id' => "p-$boxName",
+                                               'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
+                                               'generated' => true,
+                                               'content' => $content,
+                                       ];
+                                       break;
                        }
                }
 
index 82c35bb..e570633 100644 (file)
@@ -2052,73 +2052,73 @@ class Balancer {
                        return true;
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'font':
-                               if ( isset( $attribs['color'] )
-                                       || isset( $attribs['face'] )
-                                       || isset( $attribs['size'] )
-                               ) {
-                                       break;
-                               }
-                               // otherwise, fall through
-                       case 'b':
-                       case 'big':
-                       case 'blockquote':
-                       case 'body':
-                       case 'br':
-                       case 'center':
-                       case 'code':
-                       case 'dd':
-                       case 'div':
-                       case 'dl':
-                       case 'dt':
-                       case 'em':
-                       case 'embed':
-                       case 'h1':
-                       case 'h2':
-                       case 'h3':
-                       case 'h4':
-                       case 'h5':
-                       case 'h6':
-                       case 'head':
-                       case 'hr':
-                       case 'i':
-                       case 'img':
-                       case 'li':
-                       case 'listing':
-                       case 'menu':
-                       case 'meta':
-                       case 'nobr':
-                       case 'ol':
-                       case 'p':
-                       case 'pre':
-                       case 'ruby':
-                       case 's':
-                       case 'small':
-                       case 'span':
-                       case 'strong':
-                       case 'strike':
-                       case 'sub':
-                       case 'sup':
-                       case 'table':
-                       case 'tt':
-                       case 'u':
-                       case 'ul':
-                       case 'var':
-                               if ( $this->fragmentContext ) {
-                                       break;
-                               }
-                               while ( true ) {
-                                       $this->stack->pop();
-                                       $node = $this->stack->currentNode;
-                                       if (
-                                               $node->isMathmlTextIntegrationPoint() ||
-                                               $node->isHtmlIntegrationPoint() ||
-                                               $node->isHtml()
+                               case 'font':
+                                       if ( isset( $attribs['color'] )
+                                               || isset( $attribs['face'] )
+                                               || isset( $attribs['size'] )
                                        ) {
                                                break;
                                        }
-                               }
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       // otherwise, fall through
+                               case 'b':
+                               case 'big':
+                               case 'blockquote':
+                               case 'body':
+                               case 'br':
+                               case 'center':
+                               case 'code':
+                               case 'dd':
+                               case 'div':
+                               case 'dl':
+                               case 'dt':
+                               case 'em':
+                               case 'embed':
+                               case 'h1':
+                               case 'h2':
+                               case 'h3':
+                               case 'h4':
+                               case 'h5':
+                               case 'h6':
+                               case 'head':
+                               case 'hr':
+                               case 'i':
+                               case 'img':
+                               case 'li':
+                               case 'listing':
+                               case 'menu':
+                               case 'meta':
+                               case 'nobr':
+                               case 'ol':
+                               case 'p':
+                               case 'pre':
+                               case 'ruby':
+                               case 's':
+                               case 'small':
+                               case 'span':
+                               case 'strong':
+                               case 'strike':
+                               case 'sub':
+                               case 'sup':
+                               case 'table':
+                               case 'tt':
+                               case 'u':
+                               case 'ul':
+                               case 'var':
+                                       if ( $this->fragmentContext ) {
+                                               break;
+                                       }
+                                       while ( true ) {
+                                               $this->stack->pop();
+                                               $node = $this->stack->currentNode;
+                                               if (
+                                                       $node->isMathmlTextIntegrationPoint() ||
+                                                       $node->isHtmlIntegrationPoint() ||
+                                                       $node->isHtml()
+                                               ) {
+                                                       break;
+                                               }
+                                       }
+                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
                        }
                        // "Any other start tag"
                        $adjusted = ( $this->fragmentContext && $this->stack->length() === 1 ) ?
@@ -2270,56 +2270,56 @@ class Balancer {
                        }
                        if ( $node->isHtml() ) {
                                switch ( $node->localName ) {
-                               case 'select':
-                                       $stackLength = $this->stack->length();
-                                       for ( $j = $i + 1; $j < $stackLength - 1; $j++ ) {
-                                               $ancestor = $this->stack->node( $stackLength - $j - 1 );
-                                               if ( $ancestor->isHtmlNamed( 'template' ) ) {
-                                                       break;
+                                       case 'select':
+                                               $stackLength = $this->stack->length();
+                                               for ( $j = $i + 1; $j < $stackLength - 1; $j++ ) {
+                                                       $ancestor = $this->stack->node( $stackLength - $j - 1 );
+                                                       if ( $ancestor->isHtmlNamed( 'template' ) ) {
+                                                               break;
+                                                       }
+                                                       if ( $ancestor->isHtmlNamed( 'table' ) ) {
+                                                               $this->switchMode( 'inSelectInTableMode' );
+                                                               return;
+                                                       }
                                                }
-                                               if ( $ancestor->isHtmlNamed( 'table' ) ) {
-                                                       $this->switchMode( 'inSelectInTableMode' );
-                                                       return;
-                                               }
-                                       }
-                                       $this->switchMode( 'inSelectMode' );
-                                       return;
-                               case 'tr':
-                                       $this->switchMode( 'inRowMode' );
-                                       return;
-                               case 'tbody':
-                               case 'tfoot':
-                               case 'thead':
-                                       $this->switchMode( 'inTableBodyMode' );
-                                       return;
-                               case 'caption':
-                                       $this->switchMode( 'inCaptionMode' );
-                                       return;
-                               case 'colgroup':
-                                       $this->switchMode( 'inColumnGroupMode' );
-                                       return;
-                               case 'table':
-                                       $this->switchMode( 'inTableMode' );
-                                       return;
-                               case 'template':
-                                       $this->switchMode(
-                                               array_slice( $this->templateInsertionModes, -1 )[0]
-                                       );
-                                       return;
-                               case 'body':
-                                       $this->switchMode( 'inBodyMode' );
-                                       return;
-                               // OMITTED: <frameset>
-                               // OMITTED: <html>
-                               // OMITTED: <head>
-                               default:
-                                       if ( !$last ) {
-                                               // OMITTED: <head>
-                                               if ( $node->isA( BalanceSets::$tableCellSet ) ) {
-                                                       $this->switchMode( 'inCellMode' );
-                                                       return;
+                                               $this->switchMode( 'inSelectMode' );
+                                               return;
+                                       case 'tr':
+                                               $this->switchMode( 'inRowMode' );
+                                               return;
+                                       case 'tbody':
+                                       case 'tfoot':
+                                       case 'thead':
+                                               $this->switchMode( 'inTableBodyMode' );
+                                               return;
+                                       case 'caption':
+                                               $this->switchMode( 'inCaptionMode' );
+                                               return;
+                                       case 'colgroup':
+                                               $this->switchMode( 'inColumnGroupMode' );
+                                               return;
+                                       case 'table':
+                                               $this->switchMode( 'inTableMode' );
+                                               return;
+                                       case 'template':
+                                               $this->switchMode(
+                                                       array_slice( $this->templateInsertionModes, -1 )[0]
+                                               );
+                                               return;
+                                       case 'body':
+                                               $this->switchMode( 'inBodyMode' );
+                                               return;
+                                       // OMITTED: <frameset>
+                                       // OMITTED: <html>
+                                       // OMITTED: <head>
+                                       default:
+                                               if ( !$last ) {
+                                                       // OMITTED: <head>
+                                                       if ( $node->isA( BalanceSets::$tableCellSet ) ) {
+                                                               $this->switchMode( 'inCellMode' );
+                                                               return;
+                                                       }
                                                }
-                                       }
                                }
                        }
                        if ( $last ) {
@@ -2378,52 +2378,52 @@ class Balancer {
                        // Fall through to handle non-whitespace below.
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'meta':
-                               // OMITTED: in a full HTML parser, this might change the encoding.
-                               // falls through
-                       // OMITTED: <html>
-                       case 'base':
-                       case 'basefont':
-                       case 'bgsound':
-                       case 'link':
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               return true;
-                       // OMITTED: <title>
-                       // OMITTED: <noscript>
-                       case 'noframes':
-                       case 'style':
-                               return $this->parseRawText( $value, $attribs );
-                       // OMITTED: <script>
-                       case 'template':
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->afe->insertMarker();
-                               // OMITTED: frameset_ok
-                               $this->switchMode( 'inTemplateMode' );
-                               $this->templateInsertionModes[] = $this->parseMode;
-                               return true;
-                       // OMITTED: <head>
+                               case 'meta':
+                                       // OMITTED: in a full HTML parser, this might change the encoding.
+                                       // falls through
+                               // OMITTED: <html>
+                               case 'base':
+                               case 'basefont':
+                               case 'bgsound':
+                               case 'link':
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->stack->pop();
+                                       return true;
+                               // OMITTED: <title>
+                               // OMITTED: <noscript>
+                               case 'noframes':
+                               case 'style':
+                                       return $this->parseRawText( $value, $attribs );
+                               // OMITTED: <script>
+                               case 'template':
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->afe->insertMarker();
+                                       // OMITTED: frameset_ok
+                                       $this->switchMode( 'inTemplateMode' );
+                                       $this->templateInsertionModes[] = $this->parseMode;
+                                       return true;
+                               // OMITTED: <head>
                        }
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       // OMITTED: <head>
-                       // OMITTED: <body>
-                       // OMITTED: <html>
-                       case 'br':
-                               break; // handle at the bottom of the function
-                       case 'template':
-                               if ( $this->stack->indexOf( $value ) < 0 ) {
-                                       return true; // Ignore the token.
-                               }
-                               $this->stack->generateImpliedEndTags( null, true /* thorough */ );
-                               $this->stack->popTag( $value );
-                               $this->afe->clearToMarker();
-                               array_pop( $this->templateInsertionModes );
-                               $this->resetInsertionMode();
-                               return true;
-                       default:
-                               // ignore any other end tag
-                               return true;
+                               // OMITTED: <head>
+                               // OMITTED: <body>
+                               // OMITTED: <html>
+                               case 'br':
+                                       break; // handle at the bottom of the function
+                               case 'template':
+                                       if ( $this->stack->indexOf( $value ) < 0 ) {
+                                               return true; // Ignore the token.
+                                       }
+                                       $this->stack->generateImpliedEndTags( null, true /* thorough */ );
+                                       $this->stack->popTag( $value );
+                                       $this->afe->clearToMarker();
+                                       array_pop( $this->templateInsertionModes );
+                                       $this->resetInsertionMode();
+                                       return true;
+                               default:
+                                       // ignore any other end tag
+                                       return true;
                        }
                } elseif ( $token === 'comment' ) {
                        $this->stack->insertComment( $value );
@@ -2449,505 +2449,505 @@ class Balancer {
                        return true;
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       // OMITTED: <html>
-                       case 'base':
-                       case 'basefont':
-                       case 'bgsound':
-                       case 'link':
-                       case 'meta':
-                       case 'noframes':
-                       // OMITTED: <script>
-                       case 'style':
-                       case 'template':
-                       // OMITTED: <title>
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
-                       // OMITTED: <body>
-                       // OMITTED: <frameset>
-
-                       case 'address':
-                       case 'article':
-                       case 'aside':
-                       case 'blockquote':
-                       case 'center':
-                       case 'details':
-                       case 'dialog':
-                       case 'dir':
-                       case 'div':
-                       case 'dl':
-                       case 'fieldset':
-                       case 'figcaption':
-                       case 'figure':
-                       case 'footer':
-                       case 'header':
-                       case 'hgroup':
-                       case 'main':
-                       case 'nav':
-                       case 'ol':
-                       case 'p':
-                       case 'section':
-                       case 'summary':
-                       case 'ul':
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
-
-                       case 'menu':
-                               if ( $this->stack->inButtonScope( "p" ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
-                                       $this->stack->pop();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               // OMITTED: <html>
+                               case 'base':
+                               case 'basefont':
+                               case 'bgsound':
+                               case 'link':
+                               case 'meta':
+                               case 'noframes':
+                               // OMITTED: <script>
+                               case 'style':
+                               case 'template':
+                               // OMITTED: <title>
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               // OMITTED: <body>
+                               // OMITTED: <frameset>
 
-                       case 'h1':
-                       case 'h2':
-                       case 'h3':
-                       case 'h4':
-                       case 'h5':
-                       case 'h6':
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               if ( $this->stack->currentNode->isA( BalanceSets::$headingSet ) ) {
-                                       $this->stack->pop();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               case 'address':
+                               case 'article':
+                               case 'aside':
+                               case 'blockquote':
+                               case 'center':
+                               case 'details':
+                               case 'dialog':
+                               case 'dir':
+                               case 'div':
+                               case 'dl':
+                               case 'fieldset':
+                               case 'figcaption':
+                               case 'figure':
+                               case 'footer':
+                               case 'header':
+                               case 'hgroup':
+                               case 'main':
+                               case 'nav':
+                               case 'ol':
+                               case 'p':
+                               case 'section':
+                               case 'summary':
+                               case 'ul':
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'pre':
-                       case 'listing':
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->ignoreLinefeed = true;
-                               // OMITTED: frameset_ok
-                               return true;
+                               case 'menu':
+                                       if ( $this->stack->inButtonScope( "p" ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'form':
-                               if (
-                                       $this->formElementPointer &&
-                                       $this->stack->indexOf( 'template' ) < 0
-                               ) {
-                                       return true; // in a form, not in a template.
-                               }
-                               if ( $this->stack->inButtonScope( "p" ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $elt = $this->stack->insertHTMLElement( $value, $attribs );
-                               if ( $this->stack->indexOf( 'template' ) < 0 ) {
-                                       $this->formElementPointer = $elt;
-                               }
-                               return true;
+                               case 'h1':
+                               case 'h2':
+                               case 'h3':
+                               case 'h4':
+                               case 'h5':
+                               case 'h6':
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       if ( $this->stack->currentNode->isA( BalanceSets::$headingSet ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'li':
-                               // OMITTED: frameset_ok
-                               foreach ( $this->stack as $node ) {
-                                       if ( $node->isHtmlNamed( 'li' ) ) {
-                                               $this->inBodyMode( 'endtag', 'li' );
-                                               break;
+                               case 'pre':
+                               case 'listing':
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
                                        }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->ignoreLinefeed = true;
+                                       // OMITTED: frameset_ok
+                                       return true;
+
+                               case 'form':
                                        if (
-                                               $node->isA( BalanceSets::$specialSet ) &&
-                                               !$node->isA( BalanceSets::$addressDivPSet )
+                                               $this->formElementPointer &&
+                                               $this->stack->indexOf( 'template' ) < 0
                                        ) {
-                                               break;
+                                               return true; // in a form, not in a template.
                                        }
-                               }
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
-
-                       case 'dd':
-                       case 'dt':
-                               // OMITTED: frameset_ok
-                               foreach ( $this->stack as $node ) {
-                                       if ( $node->isHtmlNamed( 'dd' ) ) {
-                                               $this->inBodyMode( 'endtag', 'dd' );
-                                               break;
+                                       if ( $this->stack->inButtonScope( "p" ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
                                        }
-                                       if ( $node->isHtmlNamed( 'dt' ) ) {
-                                               $this->inBodyMode( 'endtag', 'dt' );
-                                               break;
+                                       $elt = $this->stack->insertHTMLElement( $value, $attribs );
+                                       if ( $this->stack->indexOf( 'template' ) < 0 ) {
+                                               $this->formElementPointer = $elt;
                                        }
-                                       if (
-                                               $node->isA( BalanceSets::$specialSet ) &&
-                                               !$node->isA( BalanceSets::$addressDivPSet )
-                                       ) {
-                                               break;
+                                       return true;
+
+                               case 'li':
+                                       // OMITTED: frameset_ok
+                                       foreach ( $this->stack as $node ) {
+                                               if ( $node->isHtmlNamed( 'li' ) ) {
+                                                       $this->inBodyMode( 'endtag', 'li' );
+                                                       break;
+                                               }
+                                               if (
+                                                       $node->isA( BalanceSets::$specialSet ) &&
+                                                       !$node->isA( BalanceSets::$addressDivPSet )
+                                               ) {
+                                                       break;
+                                               }
                                        }
-                               }
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       // OMITTED: <plaintext>
+                               case 'dd':
+                               case 'dt':
+                                       // OMITTED: frameset_ok
+                                       foreach ( $this->stack as $node ) {
+                                               if ( $node->isHtmlNamed( 'dd' ) ) {
+                                                       $this->inBodyMode( 'endtag', 'dd' );
+                                                       break;
+                                               }
+                                               if ( $node->isHtmlNamed( 'dt' ) ) {
+                                                       $this->inBodyMode( 'endtag', 'dt' );
+                                                       break;
+                                               }
+                                               if (
+                                                       $node->isA( BalanceSets::$specialSet ) &&
+                                                       !$node->isA( BalanceSets::$addressDivPSet )
+                                               ) {
+                                                       break;
+                                               }
+                                       }
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'button':
-                               if ( $this->stack->inScope( 'button' ) ) {
-                                       $this->inBodyMode( 'endtag', 'button' );
-                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               // OMITTED: <plaintext>
 
-                       case 'a':
-                               $activeElement = $this->afe->findElementByTag( 'a' );
-                               if ( $activeElement ) {
-                                       $this->inBodyMode( 'endtag', 'a' );
-                                       if ( $this->afe->isInList( $activeElement ) ) {
-                                               $this->afe->remove( $activeElement );
-                                               // Don't flatten here, since when we fall
-                                               // through below we might foster parent
-                                               // the new <a> tag inside this one.
-                                               $this->stack->removeElement( $activeElement, false );
+                               case 'button':
+                                       if ( $this->stack->inScope( 'button' ) ) {
+                                               $this->inBodyMode( 'endtag', 'button' );
+                                               return $this->insertToken( $token, $value, $attribs, $selfClose );
                                        }
-                               }
-                               // Falls through
-                       case 'b':
-                       case 'big':
-                       case 'code':
-                       case 'em':
-                       case 'font':
-                       case 'i':
-                       case 's':
-                       case 'small':
-                       case 'strike':
-                       case 'strong':
-                       case 'tt':
-                       case 'u':
-                               $this->afe->reconstruct( $this->stack );
-                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
-                               return true;
-
-                       case 'nobr':
-                               $this->afe->reconstruct( $this->stack );
-                               if ( $this->stack->inScope( 'nobr' ) ) {
-                                       $this->inBodyMode( 'endtag', 'nobr' );
                                        $this->afe->reconstruct( $this->stack );
-                               }
-                               $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
-                               return true;
-
-                       case 'applet':
-                       case 'marquee':
-                       case 'object':
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->afe->insertMarker();
-                               // OMITTED: frameset_ok
-                               return true;
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'table':
-                               // The document is never in "quirks mode"; see simplifications
-                               // above.
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               // OMITTED: frameset_ok
-                               $this->switchMode( 'inTableMode' );
-                               return true;
+                               case 'a':
+                                       $activeElement = $this->afe->findElementByTag( 'a' );
+                                       if ( $activeElement ) {
+                                               $this->inBodyMode( 'endtag', 'a' );
+                                               if ( $this->afe->isInList( $activeElement ) ) {
+                                                       $this->afe->remove( $activeElement );
+                                                       // Don't flatten here, since when we fall
+                                                       // through below we might foster parent
+                                                       // the new <a> tag inside this one.
+                                                       $this->stack->removeElement( $activeElement, false );
+                                               }
+                                       }
+                                       // Falls through
+                               case 'b':
+                               case 'big':
+                               case 'code':
+                               case 'em':
+                               case 'font':
+                               case 'i':
+                               case 's':
+                               case 'small':
+                               case 'strike':
+                               case 'strong':
+                               case 'tt':
+                               case 'u':
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
+                                       return true;
 
-                       case 'area':
-                       case 'br':
-                       case 'embed':
-                       case 'img':
-                       case 'keygen':
-                       case 'wbr':
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               // OMITTED: frameset_ok
-                               return true;
+                               case 'nobr':
+                                       $this->afe->reconstruct( $this->stack );
+                                       if ( $this->stack->inScope( 'nobr' ) ) {
+                                               $this->inBodyMode( 'endtag', 'nobr' );
+                                               $this->afe->reconstruct( $this->stack );
+                                       }
+                                       $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) );
+                                       return true;
 
-                       case 'input':
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               // OMITTED: frameset_ok
-                               // (hence we don't need to examine the tag's "type" attribute)
-                               return true;
+                               case 'applet':
+                               case 'marquee':
+                               case 'object':
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->afe->insertMarker();
+                                       // OMITTED: frameset_ok
+                                       return true;
 
-                       case 'param':
-                       case 'source':
-                       case 'track':
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               return true;
+                               case 'table':
+                                       // The document is never in "quirks mode"; see simplifications
+                                       // above.
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       // OMITTED: frameset_ok
+                                       $this->switchMode( 'inTableMode' );
+                                       return true;
 
-                       case 'hr':
-                               if ( $this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'endtag', 'p' );
-                               }
-                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                               case 'area':
+                               case 'br':
+                               case 'embed':
+                               case 'img':
+                               case 'keygen':
+                               case 'wbr':
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
                                        $this->stack->pop();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               return true;
-
-                       case 'image':
-                               // warts!
-                               return $this->inBodyMode( $token, 'img', $attribs, $selfClose );
-
-                       case 'textarea':
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->ignoreLinefeed = true;
-                               $this->inRCDATA = $value; // emulate rcdata tokenizer mode
-                               // OMITTED: frameset_ok
-                               return true;
-
-                       // OMITTED: <xmp>
-                       // OMITTED: <iframe>
-                       // OMITTED: <noembed>
-                       // OMITTED: <noscript>
-
-                       case 'select':
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               switch ( $this->parseMode ) {
-                               case 'inTableMode':
-                               case 'inCaptionMode':
-                               case 'inTableBodyMode':
-                               case 'inRowMode':
-                               case 'inCellMode':
-                                       $this->switchMode( 'inSelectInTableMode' );
+                                       // OMITTED: frameset_ok
                                        return true;
-                               default:
-                                       $this->switchMode( 'inSelectMode' );
+
+                               case 'input':
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->stack->pop();
+                                       // OMITTED: frameset_ok
+                                       // (hence we don't need to examine the tag's "type" attribute)
                                        return true;
-                               }
 
-                       case 'optgroup':
-                       case 'option':
-                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
-                                       $this->inBodyMode( 'endtag', 'option' );
-                               }
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               case 'param':
+                               case 'source':
+                               case 'track':
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->stack->pop();
+                                       return true;
 
-                       case 'menuitem':
-                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                               case 'hr':
+                                       if ( $this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'endtag', 'p' );
+                                       }
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
                                        $this->stack->pop();
-                               }
-                               $this->afe->reconstruct( $this->stack );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                                       return true;
 
-                       case 'rb':
-                       case 'rtc':
-                               if ( $this->stack->inScope( 'ruby' ) ) {
-                                       $this->stack->generateImpliedEndTags();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               case 'image':
+                                       // warts!
+                                       return $this->inBodyMode( $token, 'img', $attribs, $selfClose );
 
-                       case 'rp':
-                       case 'rt':
-                               if ( $this->stack->inScope( 'ruby' ) ) {
-                                       $this->stack->generateImpliedEndTags( 'rtc' );
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
+                               case 'textarea':
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->ignoreLinefeed = true;
+                                       $this->inRCDATA = $value; // emulate rcdata tokenizer mode
+                                       // OMITTED: frameset_ok
+                                       return true;
 
-                       case 'math':
-                               $this->afe->reconstruct( $this->stack );
-                               // We skip the spec's "adjust MathML attributes" and
-                               // "adjust foreign attributes" steps, since the browser will
-                               // do this later when it parses the output and it doesn't affect
-                               // balancing.
-                               $this->stack->insertForeignElement(
-                                       BalanceSets::MATHML_NAMESPACE, $value, $attribs
-                               );
-                               if ( $selfClose ) {
-                                       // emit explicit </math> tag.
-                                       $this->stack->pop();
-                               }
-                               return true;
+                               // OMITTED: <xmp>
+                               // OMITTED: <iframe>
+                               // OMITTED: <noembed>
+                               // OMITTED: <noscript>
 
-                       case 'svg':
-                               $this->afe->reconstruct( $this->stack );
-                               // We skip the spec's "adjust SVG attributes" and
-                               // "adjust foreign attributes" steps, since the browser will
-                               // do this later when it parses the output and it doesn't affect
-                               // balancing.
-                               $this->stack->insertForeignElement(
-                                       BalanceSets::SVG_NAMESPACE, $value, $attribs
-                               );
-                               if ( $selfClose ) {
-                                       // emit explicit </svg> tag.
-                                       $this->stack->pop();
-                               }
-                               return true;
+                               case 'select':
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       switch ( $this->parseMode ) {
+                                               case 'inTableMode':
+                                               case 'inCaptionMode':
+                                               case 'inTableBodyMode':
+                                               case 'inRowMode':
+                                               case 'inCellMode':
+                                                       $this->switchMode( 'inSelectInTableMode' );
+                                                       return true;
+                                               default:
+                                                       $this->switchMode( 'inSelectMode' );
+                                                       return true;
+                                       }
 
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <frame>
-                       case 'head':
-                       case 'tbody':
-                       case 'td':
-                       case 'tfoot':
-                       case 'th':
-                       case 'thead':
-                       case 'tr':
-                               // Ignore table tags if we're not inTableMode
-                               return true;
-                       }
+                               case 'optgroup':
+                               case 'option':
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                               $this->inBodyMode( 'endtag', 'option' );
+                                       }
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       // Handle any other start tag here
-                       $this->afe->reconstruct( $this->stack );
-                       $this->stack->insertHTMLElement( $value, $attribs );
-                       return true;
-               } elseif ( $token === 'endtag' ) {
-                       switch ( $value ) {
-                       // </body>,</html> are unsupported.
-
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
-
-                       case 'address':
-                       case 'article':
-                       case 'aside':
-                       case 'blockquote':
-                       case 'button':
-                       case 'center':
-                       case 'details':
-                       case 'dialog':
-                       case 'dir':
-                       case 'div':
-                       case 'dl':
-                       case 'fieldset':
-                       case 'figcaption':
-                       case 'figure':
-                       case 'footer':
-                       case 'header':
-                       case 'hgroup':
-                       case 'listing':
-                       case 'main':
-                       case 'menu':
-                       case 'nav':
-                       case 'ol':
-                       case 'pre':
-                       case 'section':
-                       case 'summary':
-                       case 'ul':
-                               // Ignore if there is not a matching open tag
-                               if ( !$this->stack->inScope( $value ) ) {
+                               case 'menuitem':
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->afe->reconstruct( $this->stack );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
                                        return true;
-                               }
-                               $this->stack->generateImpliedEndTags();
-                               $this->stack->popTag( $value );
-                               return true;
 
-                       case 'form':
-                               if ( $this->stack->indexOf( 'template' ) < 0 ) {
-                                       $openform = $this->formElementPointer;
-                                       $this->formElementPointer = null;
-                                       if ( !$openform || !$this->stack->inScope( $openform ) ) {
-                                               return true;
+                               case 'rb':
+                               case 'rtc':
+                                       if ( $this->stack->inScope( 'ruby' ) ) {
+                                               $this->stack->generateImpliedEndTags();
                                        }
-                                       $this->stack->generateImpliedEndTags();
-                                       // Don't flatten yet if we're removing a <form> element
-                                       // out-of-order. (eg. `<form><div></form>`)
-                                       $flatten = ( $this->stack->currentNode === $openform );
-                                       $this->stack->removeElement( $openform, $flatten );
-                               } else {
-                                       if ( !$this->stack->inScope( 'form' ) ) {
-                                               return true;
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
+
+                               case 'rp':
+                               case 'rt':
+                                       if ( $this->stack->inScope( 'ruby' ) ) {
+                                               $this->stack->generateImpliedEndTags( 'rtc' );
                                        }
-                                       $this->stack->generateImpliedEndTags();
-                                       $this->stack->popTag( 'form' );
-                               }
-                               return true;
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
 
-                       case 'p':
-                               if ( !$this->stack->inButtonScope( 'p' ) ) {
-                                       $this->inBodyMode( 'tag', 'p', [] );
-                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               $this->stack->generateImpliedEndTags( $value );
-                               $this->stack->popTag( $value );
-                               return true;
+                               case 'math':
+                                       $this->afe->reconstruct( $this->stack );
+                                       // We skip the spec's "adjust MathML attributes" and
+                                       // "adjust foreign attributes" steps, since the browser will
+                                       // do this later when it parses the output and it doesn't affect
+                                       // balancing.
+                                       $this->stack->insertForeignElement(
+                                               BalanceSets::MATHML_NAMESPACE, $value, $attribs
+                                       );
+                                       if ( $selfClose ) {
+                                               // emit explicit </math> tag.
+                                               $this->stack->pop();
+                                       }
+                                       return true;
 
-                       case 'li':
-                               if ( !$this->stack->inListItemScope( $value ) ) {
-                                       return true; // ignore
-                               }
-                               $this->stack->generateImpliedEndTags( $value );
-                               $this->stack->popTag( $value );
-                               return true;
+                               case 'svg':
+                                       $this->afe->reconstruct( $this->stack );
+                                       // We skip the spec's "adjust SVG attributes" and
+                                       // "adjust foreign attributes" steps, since the browser will
+                                       // do this later when it parses the output and it doesn't affect
+                                       // balancing.
+                                       $this->stack->insertForeignElement(
+                                               BalanceSets::SVG_NAMESPACE, $value, $attribs
+                                       );
+                                       if ( $selfClose ) {
+                                               // emit explicit </svg> tag.
+                                               $this->stack->pop();
+                                       }
+                                       return true;
 
-                       case 'dd':
-                       case 'dt':
-                               if ( !$this->stack->inScope( $value ) ) {
-                                       return true; // ignore
-                               }
-                               $this->stack->generateImpliedEndTags( $value );
-                               $this->stack->popTag( $value );
-                               return true;
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <frame>
+                               case 'head':
+                               case 'tbody':
+                               case 'td':
+                               case 'tfoot':
+                               case 'th':
+                               case 'thead':
+                               case 'tr':
+                                       // Ignore table tags if we're not inTableMode
+                                       return true;
+                       }
 
-                       case 'h1':
-                       case 'h2':
-                       case 'h3':
-                       case 'h4':
-                       case 'h5':
-                       case 'h6':
-                               if ( !$this->stack->inScope( BalanceSets::$headingSet ) ) {
-                                       return true; // ignore
-                               }
-                               $this->stack->generateImpliedEndTags();
-                               $this->stack->popTag( BalanceSets::$headingSet );
-                               return true;
+                       // Handle any other start tag here
+                       $this->afe->reconstruct( $this->stack );
+                       $this->stack->insertHTMLElement( $value, $attribs );
+                       return true;
+               } elseif ( $token === 'endtag' ) {
+                       switch ( $value ) {
+                               // </body>,</html> are unsupported.
 
-                       case 'sarcasm':
-                               // Take a deep breath, then:
-                               break;
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+
+                               case 'address':
+                               case 'article':
+                               case 'aside':
+                               case 'blockquote':
+                               case 'button':
+                               case 'center':
+                               case 'details':
+                               case 'dialog':
+                               case 'dir':
+                               case 'div':
+                               case 'dl':
+                               case 'fieldset':
+                               case 'figcaption':
+                               case 'figure':
+                               case 'footer':
+                               case 'header':
+                               case 'hgroup':
+                               case 'listing':
+                               case 'main':
+                               case 'menu':
+                               case 'nav':
+                               case 'ol':
+                               case 'pre':
+                               case 'section':
+                               case 'summary':
+                               case 'ul':
+                                       // Ignore if there is not a matching open tag
+                                       if ( !$this->stack->inScope( $value ) ) {
+                                               return true;
+                                       }
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( $value );
+                                       return true;
 
-                       case 'a':
-                       case 'b':
-                       case 'big':
-                       case 'code':
-                       case 'em':
-                       case 'font':
-                       case 'i':
-                       case 'nobr':
-                       case 's':
-                       case 'small':
-                       case 'strike':
-                       case 'strong':
-                       case 'tt':
-                       case 'u':
-                               if ( $this->stack->adoptionAgency( $value, $this->afe ) ) {
-                                       return true; // If we did something, we're done.
-                               }
-                               break; // Go to the "any other end tag" case.
+                               case 'form':
+                                       if ( $this->stack->indexOf( 'template' ) < 0 ) {
+                                               $openform = $this->formElementPointer;
+                                               $this->formElementPointer = null;
+                                               if ( !$openform || !$this->stack->inScope( $openform ) ) {
+                                                       return true;
+                                               }
+                                               $this->stack->generateImpliedEndTags();
+                                               // Don't flatten yet if we're removing a <form> element
+                                               // out-of-order. (eg. `<form><div></form>`)
+                                               $flatten = ( $this->stack->currentNode === $openform );
+                                               $this->stack->removeElement( $openform, $flatten );
+                                       } else {
+                                               if ( !$this->stack->inScope( 'form' ) ) {
+                                                       return true;
+                                               }
+                                               $this->stack->generateImpliedEndTags();
+                                               $this->stack->popTag( 'form' );
+                                       }
+                                       return true;
 
-                       case 'applet':
-                       case 'marquee':
-                       case 'object':
-                               if ( !$this->stack->inScope( $value ) ) {
-                                       return true; // ignore
-                               }
-                               $this->stack->generateImpliedEndTags();
-                               $this->stack->popTag( $value );
-                               $this->afe->clearToMarker();
-                               return true;
+                               case 'p':
+                                       if ( !$this->stack->inButtonScope( 'p' ) ) {
+                                               $this->inBodyMode( 'tag', 'p', [] );
+                                               return $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       $this->stack->generateImpliedEndTags( $value );
+                                       $this->stack->popTag( $value );
+                                       return true;
 
-                       case 'br':
-                               // Turn </br> into <br>
-                               return $this->inBodyMode( 'tag', $value, [] );
+                               case 'li':
+                                       if ( !$this->stack->inListItemScope( $value ) ) {
+                                               return true; // ignore
+                                       }
+                                       $this->stack->generateImpliedEndTags( $value );
+                                       $this->stack->popTag( $value );
+                                       return true;
+
+                               case 'dd':
+                               case 'dt':
+                                       if ( !$this->stack->inScope( $value ) ) {
+                                               return true; // ignore
+                                       }
+                                       $this->stack->generateImpliedEndTags( $value );
+                                       $this->stack->popTag( $value );
+                                       return true;
+
+                               case 'h1':
+                               case 'h2':
+                               case 'h3':
+                               case 'h4':
+                               case 'h5':
+                               case 'h6':
+                                       if ( !$this->stack->inScope( BalanceSets::$headingSet ) ) {
+                                               return true; // ignore
+                                       }
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( BalanceSets::$headingSet );
+                                       return true;
+
+                               case 'sarcasm':
+                                       // Take a deep breath, then:
+                                       break;
+
+                               case 'a':
+                               case 'b':
+                               case 'big':
+                               case 'code':
+                               case 'em':
+                               case 'font':
+                               case 'i':
+                               case 'nobr':
+                               case 's':
+                               case 'small':
+                               case 'strike':
+                               case 'strong':
+                               case 'tt':
+                               case 'u':
+                                       if ( $this->stack->adoptionAgency( $value, $this->afe ) ) {
+                                               return true; // If we did something, we're done.
+                                       }
+                                       break; // Go to the "any other end tag" case.
+
+                               case 'applet':
+                               case 'marquee':
+                               case 'object':
+                                       if ( !$this->stack->inScope( $value ) ) {
+                                               return true; // ignore
+                                       }
+                                       $this->stack->generateImpliedEndTags();
+                                       $this->stack->popTag( $value );
+                                       $this->afe->clearToMarker();
+                                       return true;
+
+                               case 'br':
+                                       // Turn </br> into <br>
+                                       return $this->inBodyMode( 'tag', $value, [] );
                        }
 
                        // Any other end tag goes here
@@ -2985,87 +2985,87 @@ class Balancer {
                        return true;
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'caption':
-                               $this->afe->insertMarker();
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->switchMode( 'inCaptionMode' );
-                               return true;
-                       case 'colgroup':
-                               $this->stack->clearToContext( BalanceSets::$tableContextSet );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->switchMode( 'inColumnGroupMode' );
-                               return true;
-                       case 'col':
-                               $this->inTableMode( 'tag', 'colgroup', [] );
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                               $this->stack->clearToContext( BalanceSets::$tableContextSet );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->switchMode( 'inTableBodyMode' );
-                               return true;
-                       case 'td':
-                       case 'th':
-                       case 'tr':
-                               $this->inTableMode( 'tag', 'tbody', [] );
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
-                       case 'table':
-                               if ( !$this->stack->inTableScope( $value ) ) {
-                                       return true; // Ignore this tag.
-                               }
-                               $this->inTableMode( 'endtag', $value );
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
-
-                       case 'style':
-                       // OMITTED: <script>
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'caption':
+                                       $this->afe->insertMarker();
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->switchMode( 'inCaptionMode' );
+                                       return true;
+                               case 'colgroup':
+                                       $this->stack->clearToContext( BalanceSets::$tableContextSet );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->switchMode( 'inColumnGroupMode' );
+                                       return true;
+                               case 'col':
+                                       $this->inTableMode( 'tag', 'colgroup', [] );
+                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       $this->stack->clearToContext( BalanceSets::$tableContextSet );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->switchMode( 'inTableBodyMode' );
+                                       return true;
+                               case 'td':
+                               case 'th':
+                               case 'tr':
+                                       $this->inTableMode( 'tag', 'tbody', [] );
+                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
+                               case 'table':
+                                       if ( !$this->stack->inTableScope( $value ) ) {
+                                               return true; // Ignore this tag.
+                                       }
+                                       $this->inTableMode( 'endtag', $value );
+                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
 
-                       case 'input':
-                               if ( !isset( $attribs['type'] ) || strcasecmp( $attribs['type'], 'hidden' ) !== 0 ) {
-                                       break; // Handle this as "everything else"
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               return true;
+                               case 'style':
+                               // OMITTED: <script>
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
 
-                       case 'form':
-                               if (
-                                       $this->formElementPointer ||
-                                       $this->stack->indexOf( 'template' ) >= 0
-                               ) {
-                                       return true; // ignore this token
-                               }
-                               $this->formElementPointer =
+                               case 'input':
+                                       if ( !isset( $attribs['type'] ) || strcasecmp( $attribs['type'], 'hidden' ) !== 0 ) {
+                                               break; // Handle this as "everything else"
+                                       }
                                        $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->popTag( $this->formElementPointer );
-                               return true;
+                                       $this->stack->pop();
+                                       return true;
+
+                               case 'form':
+                                       if (
+                                               $this->formElementPointer ||
+                                               $this->stack->indexOf( 'template' ) >= 0
+                                       ) {
+                                               return true; // ignore this token
+                                       }
+                                       $this->formElementPointer =
+                                               $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->stack->popTag( $this->formElementPointer );
+                                       return true;
                        }
                        // Fall through for "anything else" clause.
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'table':
-                               if ( !$this->stack->inTableScope( $value ) ) {
-                                       return true; // Ignore.
-                               }
-                               $this->stack->popTag( $value );
-                               $this->resetInsertionMode();
-                               return true;
-                       // OMITTED: <body>
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <html>
-                       case 'tbody':
-                       case 'td':
-                       case 'tfoot':
-                       case 'th':
-                       case 'thead':
-                       case 'tr':
-                               return true; // Ignore the token.
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'table':
+                                       if ( !$this->stack->inTableScope( $value ) ) {
+                                               return true; // Ignore.
+                                       }
+                                       $this->stack->popTag( $value );
+                                       $this->resetInsertionMode();
+                                       return true;
+                               // OMITTED: <body>
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <html>
+                               case 'tbody':
+                               case 'td':
+                               case 'tfoot':
+                               case 'th':
+                               case 'thead':
+                               case 'tr':
+                                       return true; // Ignore the token.
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                        // Fall through for "anything else" clause.
                } elseif ( $token === 'comment' ) {
@@ -3116,43 +3116,43 @@ class Balancer {
        private function inCaptionMode( $token, $value, $attribs = null, $selfClose = false ) {
                if ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       case 'tbody':
-                       case 'td':
-                       case 'tfoot':
-                       case 'th':
-                       case 'thead':
-                       case 'tr':
-                               if ( $this->endCaption() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               case 'tbody':
+                               case 'td':
+                               case 'tfoot':
+                               case 'th':
+                               case 'thead':
+                               case 'tr':
+                                       if ( $this->endCaption() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                        }
                        // Fall through to "anything else" case.
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'caption':
-                               $this->endCaption();
-                               return true;
-                       case 'table':
-                               if ( $this->endCaption() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
-                       case 'body':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <html>
-                       case 'tbody':
-                       case 'td':
-                       case 'tfoot':
-                       case 'th':
-                       case 'thead':
-                       case 'tr':
-                               // Ignore the token
-                               return true;
+                               case 'caption':
+                                       $this->endCaption();
+                                       return true;
+                               case 'table':
+                                       if ( $this->endCaption() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
+                               case 'body':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <html>
+                               case 'tbody':
+                               case 'td':
+                               case 'tfoot':
+                               case 'th':
+                               case 'thead':
+                               case 'tr':
+                                       // Ignore the token
+                                       return true;
                        }
                        // Fall through to "anything else" case.
                }
@@ -3172,28 +3172,28 @@ class Balancer {
                        // Fall through to handle non-whitespace below.
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       // OMITTED: <html>
-                       case 'col':
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->stack->pop();
-                               return true;
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               // OMITTED: <html>
+                               case 'col':
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->stack->pop();
+                                       return true;
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                        // Fall through for "anything else".
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'colgroup':
-                               if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
+                               case 'colgroup':
+                                       if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
+                                               return true; // Ignore the token.
+                                       }
+                                       $this->stack->pop();
+                                       $this->switchMode( 'inTableMode' );
+                                       return true;
+                               case 'col':
                                        return true; // Ignore the token.
-                               }
-                               $this->stack->pop();
-                               $this->switchMode( 'inTableMode' );
-                               return true;
-                       case 'col':
-                               return true; // Ignore the token.
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                        // Fall through for "anything else".
                } elseif ( $token === 'eof' ) {
@@ -3228,50 +3228,50 @@ class Balancer {
        private function inTableBodyMode( $token, $value, $attribs = null, $selfClose = false ) {
                if ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'tr':
-                               $this->stack->clearToContext( BalanceSets::$tableBodyContextSet );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->switchMode( 'inRowMode' );
-                               return true;
-                       case 'th':
-                       case 'td':
-                               $this->inTableBodyMode( 'tag', 'tr', [] );
-                               $this->insertToken( $token, $value, $attribs, $selfClose );
-                               return true;
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                               if ( $this->endSection() ) {
+                               case 'tr':
+                                       $this->stack->clearToContext( BalanceSets::$tableBodyContextSet );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->switchMode( 'inRowMode' );
+                                       return true;
+                               case 'th':
+                               case 'td':
+                                       $this->inTableBodyMode( 'tag', 'tr', [] );
                                        $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
+                                       return true;
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       if ( $this->endSection() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                        }
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'table':
-                               if ( $this->endSection() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                               if ( $this->stack->inTableScope( $value ) ) {
-                                       $this->endSection();
-                               }
-                               return true;
-                       // OMITTED: <body>
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <html>
-                       case 'td':
-                       case 'th':
-                       case 'tr':
-                               return true; // Ignore the token.
+                               case 'table':
+                                       if ( $this->endSection() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       if ( $this->stack->inTableScope( $value ) ) {
+                                               $this->endSection();
+                                       }
+                                       return true;
+                               // OMITTED: <body>
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <html>
+                               case 'td':
+                               case 'th':
+                               case 'tr':
+                                       return true; // Ignore the token.
                        }
                }
                // Anything else:
@@ -3291,53 +3291,53 @@ class Balancer {
        private function inRowMode( $token, $value, $attribs = null, $selfClose = false ) {
                if ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'th':
-                       case 'td':
-                               $this->stack->clearToContext( BalanceSets::$tableRowContextSet );
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               $this->switchMode( 'inCellMode' );
-                               $this->afe->insertMarker();
-                               return true;
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                       case 'tr':
-                               if ( $this->endRow() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
+                               case 'th':
+                               case 'td':
+                                       $this->stack->clearToContext( BalanceSets::$tableRowContextSet );
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       $this->switchMode( 'inCellMode' );
+                                       $this->afe->insertMarker();
+                                       return true;
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                               case 'tr':
+                                       if ( $this->endRow() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                        }
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'tr':
-                               $this->endRow();
-                               return true;
-                       case 'table':
-                               if ( $this->endRow() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                               if (
-                                       $this->stack->inTableScope( $value ) &&
-                                       $this->endRow()
-                               ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
-                       // OMITTED: <body>
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <html>
-                       case 'td':
-                       case 'th':
-                               return true; // Ignore the token.
+                               case 'tr':
+                                       $this->endRow();
+                                       return true;
+                               case 'table':
+                                       if ( $this->endRow() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       if (
+                                               $this->stack->inTableScope( $value ) &&
+                                               $this->endRow()
+                                       ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
+                               // OMITTED: <body>
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <html>
+                               case 'td':
+                               case 'th':
+                                       return true; // Ignore the token.
                        }
                }
                // Anything else:
@@ -3359,51 +3359,51 @@ class Balancer {
        private function inCellMode( $token, $value, $attribs = null, $selfClose = false ) {
                if ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       case 'tbody':
-                       case 'td':
-                       case 'tfoot':
-                       case 'th':
-                       case 'thead':
-                       case 'tr':
-                               if ( $this->endCell() ) {
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               case 'tbody':
+                               case 'td':
+                               case 'tfoot':
+                               case 'th':
+                               case 'thead':
+                               case 'tr':
+                                       if ( $this->endCell() ) {
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                        }
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'td':
-                       case 'th':
-                               if ( $this->stack->inTableScope( $value ) ) {
-                                       $this->stack->generateImpliedEndTags();
-                                       $this->stack->popTag( $value );
-                                       $this->afe->clearToMarker();
-                                       $this->switchMode( 'inRowMode' );
-                               }
-                               return true;
-                       // OMITTED: <body>
-                       case 'caption':
-                       case 'col':
-                       case 'colgroup':
-                       // OMITTED: <html>
-                               return true;
+                               case 'td':
+                               case 'th':
+                                       if ( $this->stack->inTableScope( $value ) ) {
+                                               $this->stack->generateImpliedEndTags();
+                                               $this->stack->popTag( $value );
+                                               $this->afe->clearToMarker();
+                                               $this->switchMode( 'inRowMode' );
+                                       }
+                                       return true;
+                               // OMITTED: <body>
+                               case 'caption':
+                               case 'col':
+                               case 'colgroup':
+                               // OMITTED: <html>
+                                       return true;
 
-                       case 'table':
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                       case 'tr':
-                               if ( $this->stack->inTableScope( $value ) ) {
-                                       $this->stack->generateImpliedEndTags();
-                                       $this->stack->popTag( BalanceSets::$tableCellSet );
-                                       $this->afe->clearToMarker();
-                                       $this->switchMode( 'inRowMode' );
-                                       $this->insertToken( $token, $value, $attribs, $selfClose );
-                               }
-                               return true;
+                               case 'table':
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                               case 'tr':
+                                       if ( $this->stack->inTableScope( $value ) ) {
+                                               $this->stack->generateImpliedEndTags();
+                                               $this->stack->popTag( BalanceSets::$tableCellSet );
+                                               $this->afe->clearToMarker();
+                                               $this->switchMode( 'inRowMode' );
+                                               $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                        }
                }
                // Anything else:
@@ -3418,65 +3418,65 @@ class Balancer {
                        return $this->inBodyMode( $token, $value, $attribs, $selfClose );
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       // OMITTED: <html>
-                       case 'option':
-                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
-                                       $this->stack->pop();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
-                       case 'optgroup':
-                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
-                                       $this->stack->pop();
-                               }
-                               if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
-                                       $this->stack->pop();
-                               }
-                               $this->stack->insertHTMLElement( $value, $attribs );
-                               return true;
-                       case 'select':
-                               $this->inSelectMode( 'endtag', $value ); // treat it like endtag
-                               return true;
-                       case 'input':
-                       case 'keygen':
-                       case 'textarea':
-                               if ( !$this->stack->inSelectScope( 'select' ) ) {
-                                       return true; // ignore token (fragment case)
-                               }
-                               $this->inSelectMode( 'endtag', 'select' );
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
-                       case 'script':
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               // OMITTED: <html>
+                               case 'option':
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
+                               case 'optgroup':
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       $this->stack->insertHTMLElement( $value, $attribs );
+                                       return true;
+                               case 'select':
+                                       $this->inSelectMode( 'endtag', $value ); // treat it like endtag
+                                       return true;
+                               case 'input':
+                               case 'keygen':
+                               case 'textarea':
+                                       if ( !$this->stack->inSelectScope( 'select' ) ) {
+                                               return true; // ignore token (fragment case)
+                                       }
+                                       $this->inSelectMode( 'endtag', 'select' );
+                                       return $this->insertToken( $token, $value, $attribs, $selfClose );
+                               case 'script':
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'optgroup':
-                               if (
-                                       $this->stack->currentNode->isHtmlNamed( 'option' ) &&
-                                       $this->stack->length() >= 2 &&
-                                       $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed( 'optgroup' )
-                               ) {
-                                       $this->stack->pop();
-                               }
-                               if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
-                                       $this->stack->pop();
-                               }
-                               return true;
-                       case 'option':
-                               if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
-                                       $this->stack->pop();
-                               }
-                               return true;
-                       case 'select':
-                               if ( !$this->stack->inSelectScope( $value ) ) {
-                                       return true; // fragment case
-                               }
-                               $this->stack->popTag( $value );
-                               $this->resetInsertionMode();
-                               return true;
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'optgroup':
+                                       if (
+                                               $this->stack->currentNode->isHtmlNamed( 'option' ) &&
+                                               $this->stack->length() >= 2 &&
+                                               $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed( 'optgroup' )
+                                       ) {
+                                               $this->stack->pop();
+                                       }
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       return true;
+                               case 'option':
+                                       if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
+                                               $this->stack->pop();
+                                       }
+                                       return true;
+                               case 'select':
+                                       if ( !$this->stack->inSelectScope( $value ) ) {
+                                               return true; // fragment case
+                                       }
+                                       $this->stack->popTag( $value );
+                                       $this->resetInsertionMode();
+                                       return true;
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                } elseif ( $token === 'comment' ) {
                        $this->stack->insertComment( $value );
@@ -3488,24 +3488,24 @@ class Balancer {
 
        private function inSelectInTableMode( $token, $value, $attribs = null, $selfClose = false ) {
                switch ( $value ) {
-               case 'caption':
-               case 'table':
-               case 'tbody':
-               case 'tfoot':
-               case 'thead':
-               case 'tr':
-               case 'td':
-               case 'th':
-                       if ( $token === 'tag' ) {
-                               $this->inSelectInTableMode( 'endtag', 'select' );
-                               return $this->insertToken( $token, $value, $attribs, $selfClose );
-                       } elseif ( $token === 'endtag' ) {
-                               if ( $this->stack->inTableScope( $value ) ) {
+                       case 'caption':
+                       case 'table':
+                       case 'tbody':
+                       case 'tfoot':
+                       case 'thead':
+                       case 'tr':
+                       case 'td':
+                       case 'th':
+                               if ( $token === 'tag' ) {
                                        $this->inSelectInTableMode( 'endtag', 'select' );
                                        return $this->insertToken( $token, $value, $attribs, $selfClose );
+                               } elseif ( $token === 'endtag' ) {
+                                       if ( $this->stack->inTableScope( $value ) ) {
+                                               $this->inSelectInTableMode( 'endtag', 'select' );
+                                               return $this->insertToken( $token, $value, $attribs, $selfClose );
+                                       }
+                                       return true;
                                }
-                               return true;
-                       }
                }
                // anything else
                return $this->inSelectMode( $token, $value, $attribs, $selfClose );
@@ -3527,50 +3527,50 @@ class Balancer {
                        return true;
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
-                       case 'base':
-                       case 'basefont':
-                       case 'bgsound':
-                       case 'link':
-                       case 'meta':
-                       case 'noframes':
-                       // OMITTED: <script>
-                       case 'style':
-                       case 'template':
-                       // OMITTED: <title>
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'base':
+                               case 'basefont':
+                               case 'bgsound':
+                               case 'link':
+                               case 'meta':
+                               case 'noframes':
+                               // OMITTED: <script>
+                               case 'style':
+                               case 'template':
+                               // OMITTED: <title>
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
 
-                       case 'caption':
-                       case 'colgroup':
-                       case 'tbody':
-                       case 'tfoot':
-                       case 'thead':
-                               return $this->switchModeAndReprocess(
-                                       'inTableMode', $token, $value, $attribs, $selfClose
-                               );
+                               case 'caption':
+                               case 'colgroup':
+                               case 'tbody':
+                               case 'tfoot':
+                               case 'thead':
+                                       return $this->switchModeAndReprocess(
+                                               'inTableMode', $token, $value, $attribs, $selfClose
+                                       );
 
-                       case 'col':
-                               return $this->switchModeAndReprocess(
-                                       'inColumnGroupMode', $token, $value, $attribs, $selfClose
-                               );
+                               case 'col':
+                                       return $this->switchModeAndReprocess(
+                                               'inColumnGroupMode', $token, $value, $attribs, $selfClose
+                                       );
 
-                       case 'tr':
-                               return $this->switchModeAndReprocess(
-                                       'inTableBodyMode', $token, $value, $attribs, $selfClose
-                               );
+                               case 'tr':
+                                       return $this->switchModeAndReprocess(
+                                               'inTableBodyMode', $token, $value, $attribs, $selfClose
+                                       );
 
-                       case 'td':
-                       case 'th':
-                               return $this->switchModeAndReprocess(
-                                       'inRowMode', $token, $value, $attribs, $selfClose
-                               );
+                               case 'td':
+                               case 'th':
+                                       return $this->switchModeAndReprocess(
+                                               'inRowMode', $token, $value, $attribs, $selfClose
+                                       );
                        }
                        return $this->switchModeAndReprocess(
                                'inBodyMode', $token, $value, $attribs, $selfClose
                        );
                } elseif ( $token === 'endtag' ) {
                        switch ( $value ) {
-                       case 'template':
-                               return $this->inHeadMode( $token, $value, $attribs, $selfClose );
+                               case 'template':
+                                       return $this->inHeadMode( $token, $value, $attribs, $selfClose );
                        }
                        return true;
                } else {
index 1415ea3..d12531b 100644 (file)
@@ -392,18 +392,18 @@ class ClassCollector {
                // Note: When changing class name discovery logic,
                // AutoLoaderTest.php may also need to be updated.
                switch ( $token[0] ) {
-               case T_NAMESPACE:
-               case T_CLASS:
-               case T_INTERFACE:
-               case T_TRAIT:
-               case T_DOUBLE_COLON:
-                       $this->startToken = $token;
-                       break;
-               case T_STRING:
-                       if ( $token[1] === 'class_alias' ) {
+                       case T_NAMESPACE:
+                       case T_CLASS:
+                       case T_INTERFACE:
+                       case T_TRAIT:
+                       case T_DOUBLE_COLON:
                                $this->startToken = $token;
-                               $this->alias = [];
-                       }
+                               break;
+                       case T_STRING:
+                               if ( $token[1] === 'class_alias' ) {
+                                       $this->startToken = $token;
+                                       $this->alias = [];
+                               }
                }
        }
 
@@ -414,78 +414,78 @@ class ClassCollector {
         */
        protected function tryEndExpect( $token ) {
                switch ( $this->startToken[0] ) {
-               case T_DOUBLE_COLON:
-                       // Skip over T_CLASS after T_DOUBLE_COLON because this is something like
-                       // "self::static" which accesses the class name. It doens't define a new class.
-                       $this->startToken = null;
-                       break;
-               case T_NAMESPACE:
-                       if ( $token === ';' || $token === '{' ) {
-                               $this->namespace = $this->implodeTokens() . '\\';
-                       } else {
-                               $this->tokens[] = $token;
-                       }
-                       break;
-
-               case T_STRING:
-                       if ( $this->alias !== null ) {
-                               // Flow 1 - Two string literals:
-                               // - T_STRING  class_alias
-                               // - '('
-                               // - T_CONSTANT_ENCAPSED_STRING 'TargetClass'
-                               // - ','
-                               // - T_WHITESPACE
-                               // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
-                               // - ')'
-                               // Flow 2 - Use of ::class syntax for first parameter
-                               // - T_STRING  class_alias
-                               // - '('
-                               // - T_STRING TargetClass
-                               // - T_DOUBLE_COLON ::
-                               // - T_CLASS class
-                               // - ','
-                               // - T_WHITESPACE
-                               // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
-                               // - ')'
-                               if ( $token === '(' ) {
-                                       // Start of a function call to class_alias()
-                                       $this->alias = [ 'target' => false, 'name' => false ];
-                               } elseif ( $token === ',' ) {
-                                       // Record that we're past the first parameter
-                                       if ( $this->alias['target'] === false ) {
-                                               $this->alias['target'] = true;
-                                       }
-                               } elseif ( is_array( $token ) && $token[0] === T_CONSTANT_ENCAPSED_STRING ) {
-                                       if ( $this->alias['target'] === true ) {
-                                               // We already saw a first argument, this must be the second.
-                                               // Strip quotes from the string literal.
-                                               $this->alias['name'] = substr( $token[1], 1, -1 );
+                       case T_DOUBLE_COLON:
+                               // Skip over T_CLASS after T_DOUBLE_COLON because this is something like
+                               // "self::static" which accesses the class name. It doens't define a new class.
+                               $this->startToken = null;
+                               break;
+                       case T_NAMESPACE:
+                               if ( $token === ';' || $token === '{' ) {
+                                       $this->namespace = $this->implodeTokens() . '\\';
+                               } else {
+                                       $this->tokens[] = $token;
+                               }
+                               break;
+
+                       case T_STRING:
+                               if ( $this->alias !== null ) {
+                                       // Flow 1 - Two string literals:
+                                       // - T_STRING  class_alias
+                                       // - '('
+                                       // - T_CONSTANT_ENCAPSED_STRING 'TargetClass'
+                                       // - ','
+                                       // - T_WHITESPACE
+                                       // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
+                                       // - ')'
+                                       // Flow 2 - Use of ::class syntax for first parameter
+                                       // - T_STRING  class_alias
+                                       // - '('
+                                       // - T_STRING TargetClass
+                                       // - T_DOUBLE_COLON ::
+                                       // - T_CLASS class
+                                       // - ','
+                                       // - T_WHITESPACE
+                                       // - T_CONSTANT_ENCAPSED_STRING 'AliasName'
+                                       // - ')'
+                                       if ( $token === '(' ) {
+                                               // Start of a function call to class_alias()
+                                               $this->alias = [ 'target' => false, 'name' => false ];
+                                       } elseif ( $token === ',' ) {
+                                               // Record that we're past the first parameter
+                                               if ( $this->alias['target'] === false ) {
+                                                       $this->alias['target'] = true;
+                                               }
+                                       } elseif ( is_array( $token ) && $token[0] === T_CONSTANT_ENCAPSED_STRING ) {
+                                               if ( $this->alias['target'] === true ) {
+                                                       // We already saw a first argument, this must be the second.
+                                                       // Strip quotes from the string literal.
+                                                       $this->alias['name'] = substr( $token[1], 1, -1 );
+                                               }
+                                       } elseif ( $token === ')' ) {
+                                               // End of function call
+                                               $this->classes[] = $this->alias['name'];
+                                               $this->alias = null;
+                                               $this->startToken = null;
+                                       } elseif ( !is_array( $token ) || (
+                                               $token[0] !== T_STRING &&
+                                               $token[0] !== T_DOUBLE_COLON &&
+                                               $token[0] !== T_CLASS &&
+                                               $token[0] !== T_WHITESPACE
+                                       ) ) {
+                                               // Ignore this call to class_alias() - compat/Timestamp.php
+                                               $this->alias = null;
+                                               $this->startToken = null;
                                        }
-                               } elseif ( $token === ')' ) {
-                                       // End of function call
-                                       $this->classes[] = $this->alias['name'];
-                                       $this->alias = null;
-                                       $this->startToken = null;
-                               } elseif ( !is_array( $token ) || (
-                                       $token[0] !== T_STRING &&
-                                       $token[0] !== T_DOUBLE_COLON &&
-                                       $token[0] !== T_CLASS &&
-                                       $token[0] !== T_WHITESPACE
-                               ) ) {
-                                       // Ignore this call to class_alias() - compat/Timestamp.php
-                                       $this->alias = null;
-                                       $this->startToken = null;
                                }
-                       }
-                       break;
-
-               case T_CLASS:
-               case T_INTERFACE:
-               case T_TRAIT:
-                       $this->tokens[] = $token;
-                       if ( is_array( $token ) && $token[0] === T_STRING ) {
-                               $this->classes[] = $this->namespace . $this->implodeTokens();
-                       }
+                               break;
+
+                       case T_CLASS:
+                       case T_INTERFACE:
+                       case T_TRAIT:
+                               $this->tokens[] = $token;
+                               if ( is_array( $token ) && $token[0] === T_STRING ) {
+                                       $this->classes[] = $this->namespace . $this->implodeTokens();
+                               }
                }
        }
 
index 554dda9..153b313 100644 (file)
@@ -37,133 +37,133 @@ class AvroValidator {
         */
        public static function getErrors( AvroSchema $schema, $datum ) {
                switch ( $schema->type ) {
-               case AvroSchema::NULL_TYPE:
-                       if ( !is_null( $datum ) ) {
-                               return self::wrongType( 'null', $datum );
-                       }
-                       return [];
-               case AvroSchema::BOOLEAN_TYPE:
-                       if ( !is_bool( $datum ) ) {
-                               return self::wrongType( 'boolean', $datum );
-                       }
-                       return [];
-               case AvroSchema::STRING_TYPE:
-               case AvroSchema::BYTES_TYPE:
-                       if ( !is_string( $datum ) ) {
-                               return self::wrongType( 'string', $datum );
-                       }
-                       return [];
-               case AvroSchema::INT_TYPE:
-                       if ( !is_int( $datum ) ) {
-                               return self::wrongType( 'integer', $datum );
-                       }
-                       if ( AvroSchema::INT_MIN_VALUE > $datum
-                               || $datum > AvroSchema::INT_MAX_VALUE
-                       ) {
-                               return self::outOfRange(
-                                       AvroSchema::INT_MIN_VALUE,
-                                       AvroSchema::INT_MAX_VALUE,
-                                       $datum
-                               );
-                       }
-                       return [];
-               case AvroSchema::LONG_TYPE:
-                       if ( !is_int( $datum ) ) {
-                               return self::wrongType( 'integer', $datum );
-                       }
-                       if ( AvroSchema::LONG_MIN_VALUE > $datum
-                               || $datum > AvroSchema::LONG_MAX_VALUE
-                       ) {
-                               return self::outOfRange(
-                                       AvroSchema::LONG_MIN_VALUE,
-                                       AvroSchema::LONG_MAX_VALUE,
-                                       $datum
-                               );
-                       }
-                       return [];
-               case AvroSchema::FLOAT_TYPE:
-               case AvroSchema::DOUBLE_TYPE:
-                       if ( !is_float( $datum ) && !is_int( $datum ) ) {
-                               return self::wrongType( 'float or integer', $datum );
-                       }
-                       return [];
-               case AvroSchema::ARRAY_SCHEMA:
-                       if ( !is_array( $datum ) ) {
-                               return self::wrongType( 'array', $datum );
-                       }
-                       $errors = [];
-                       foreach ( $datum as $d ) {
-                               $result = self::getErrors( $schema->items(), $d );
-                               if ( $result ) {
+                       case AvroSchema::NULL_TYPE:
+                               if ( !is_null( $datum ) ) {
+                                       return self::wrongType( 'null', $datum );
+                               }
+                               return [];
+                       case AvroSchema::BOOLEAN_TYPE:
+                               if ( !is_bool( $datum ) ) {
+                                       return self::wrongType( 'boolean', $datum );
+                               }
+                               return [];
+                       case AvroSchema::STRING_TYPE:
+                       case AvroSchema::BYTES_TYPE:
+                               if ( !is_string( $datum ) ) {
+                                       return self::wrongType( 'string', $datum );
+                               }
+                               return [];
+                       case AvroSchema::INT_TYPE:
+                               if ( !is_int( $datum ) ) {
+                                       return self::wrongType( 'integer', $datum );
+                               }
+                               if ( AvroSchema::INT_MIN_VALUE > $datum
+                                       || $datum > AvroSchema::INT_MAX_VALUE
+                               ) {
+                                       return self::outOfRange(
+                                               AvroSchema::INT_MIN_VALUE,
+                                               AvroSchema::INT_MAX_VALUE,
+                                               $datum
+                                       );
+                               }
+                               return [];
+                       case AvroSchema::LONG_TYPE:
+                               if ( !is_int( $datum ) ) {
+                                       return self::wrongType( 'integer', $datum );
+                               }
+                               if ( AvroSchema::LONG_MIN_VALUE > $datum
+                                       || $datum > AvroSchema::LONG_MAX_VALUE
+                               ) {
+                                       return self::outOfRange(
+                                               AvroSchema::LONG_MIN_VALUE,
+                                               AvroSchema::LONG_MAX_VALUE,
+                                               $datum
+                                       );
+                               }
+                               return [];
+                       case AvroSchema::FLOAT_TYPE:
+                       case AvroSchema::DOUBLE_TYPE:
+                               if ( !is_float( $datum ) && !is_int( $datum ) ) {
+                                       return self::wrongType( 'float or integer', $datum );
+                               }
+                               return [];
+                       case AvroSchema::ARRAY_SCHEMA:
+                               if ( !is_array( $datum ) ) {
+                                       return self::wrongType( 'array', $datum );
+                               }
+                               $errors = [];
+                               foreach ( $datum as $d ) {
+                                       $result = self::getErrors( $schema->items(), $d );
+                                       if ( $result ) {
+                                               $errors[] = $result;
+                                       }
+                               }
+                               return $errors;
+                       case AvroSchema::MAP_SCHEMA:
+                               if ( !is_array( $datum ) ) {
+                                       return self::wrongType( 'array', $datum );
+                               }
+                               $errors = [];
+                               foreach ( $datum as $k => $v ) {
+                                       if ( !is_string( $k ) ) {
+                                               $errors[] = self::wrongType( 'string key', $k );
+                                       }
+                                       $result = self::getErrors( $schema->values(), $v );
+                                       if ( $result ) {
+                                               $errors[$k] = $result;
+                                       }
+                               }
+                               return $errors;
+                       case AvroSchema::UNION_SCHEMA:
+                               $errors = [];
+                               foreach ( $schema->schemas() as $schema ) {
+                                       $result = self::getErrors( $schema, $datum );
+                                       if ( !$result ) {
+                                               return [];
+                                       }
                                        $errors[] = $result;
                                }
-                       }
-                       return $errors;
-               case AvroSchema::MAP_SCHEMA:
-                       if ( !is_array( $datum ) ) {
-                               return self::wrongType( 'array', $datum );
-                       }
-                       $errors = [];
-                       foreach ( $datum as $k => $v ) {
-                               if ( !is_string( $k ) ) {
-                                       $errors[] = self::wrongType( 'string key', $k );
-                               }
-                               $result = self::getErrors( $schema->values(), $v );
-                               if ( $result ) {
-                                       $errors[$k] = $result;
-                               }
-                       }
-                       return $errors;
-               case AvroSchema::UNION_SCHEMA:
-                       $errors = [];
-                       foreach ( $schema->schemas() as $schema ) {
-                               $result = self::getErrors( $schema, $datum );
-                               if ( !$result ) {
-                                       return [];
-                               }
-                               $errors[] = $result;
-                       }
-                       if ( $errors ) {
-                               return [ "Expected any one of these to be true", $errors ];
-                       }
-                       return "No schemas provided to union";
-               case AvroSchema::ENUM_SCHEMA:
-                       if ( !in_array( $datum, $schema->symbols() ) ) {
-                               $symbols = implode( ', ', $schema->symbols );
-                               return "Expected one of $symbols but recieved $datum";
-                       }
-                       return [];
-               case AvroSchema::FIXED_SCHEMA:
-                       if ( !is_string( $datum ) ) {
-                               return self::wrongType( 'string', $datum );
-                       }
-                       $len = strlen( $datum );
-                       if ( $len !== $schema->size() ) {
-                               return "Expected string of length {$schema->size()}, "
-                                       . "but recieved one of length $len";
-                       }
-                       return [];
-               case AvroSchema::RECORD_SCHEMA:
-               case AvroSchema::ERROR_SCHEMA:
-               case AvroSchema::REQUEST_SCHEMA:
-                       if ( !is_array( $datum ) ) {
-                               return self::wrongType( 'array', $datum );
-                       }
-                       $errors = [];
-                       foreach ( $schema->fields() as $field ) {
-                               $name = $field->name();
-                               if ( !array_key_exists( $name, $datum ) ) {
-                                       $errors[$name] = 'Missing expected field';
-                                       continue;
-                               }
-                               $result = self::getErrors( $field->type(), $datum[$name] );
-                               if ( $result ) {
-                                       $errors[$name] = $result;
-                               }
-                       }
-                       return $errors;
-