Merge "Parse wikitext in gallery caption"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 27 Nov 2018 15:47:50 +0000 (15:47 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 27 Nov 2018 15:47:50 +0000 (15:47 +0000)
1  2 
includes/parser/Parser.php
tests/parser/parserTests.txt

@@@ -22,7 -22,6 +22,7 @@@
   */
  use MediaWiki\Linker\LinkRenderer;
  use MediaWiki\MediaWikiServices;
 +use MediaWiki\Special\SpecialPageFactory;
  use Wikimedia\ScopedCallback;
  
  /**
@@@ -52,6 -51,9 +52,6 @@@
   * - Parser::getPreloadText()
   *     removes <noinclude> sections and <includeonly> tags
   *
 - * Globals used:
 - *    object: $wgContLang
 - *
   * @warning $wgUser or $wgTitle or $wgRequest or $wgLang. Keep them away!
   *
   * @par Settings:
@@@ -136,9 -138,6 +136,9 @@@ class Parser 
        const TOC_START = '<mw:toc>';
        const TOC_END = '</mw:toc>';
  
 +      /** @var int Assume that no output will later be saved this many seconds after parsing */
 +      const MAX_TTS = 900;
 +
        # Persistent:
        public $mTagHooks = [];
        public $mTransparentTagHooks = [];
        public $mImageParams = [];
        public $mImageParamsMagicArray = [];
        public $mMarkerIndex = 0;
 +      /**
 +       * @var bool Whether firstCallInit still needs to be called
 +       */
        public $mFirstCall = true;
  
        # Initialised by initialiseVariables()
         */
        protected $mLinkRenderer;
  
 +      /** @var MagicWordFactory */
 +      private $magicWordFactory;
 +
 +      /** @var Language */
 +      private $contLang;
 +
 +      /** @var ParserFactory */
 +      private $factory;
 +
 +      /** @var SpecialPageFactory */
 +      private $specialPageFactory;
 +
 +      /** @var Config */
 +      private $siteConfig;
 +
        /**
 -       * @param array $conf
 +       * @param array $parserConf See $wgParserConf documentation
 +       * @param MagicWordFactory|null $magicWordFactory
 +       * @param Language|null $contLang Content language
 +       * @param ParserFactory|null $factory
 +       * @param string|null $urlProtocols As returned from wfUrlProtocols()
 +       * @param SpecialPageFactory|null $spFactory
 +       * @param Config|null $siteConfig
         */
 -      public function __construct( $conf = [] ) {
 -              $this->mConf = $conf;
 -              $this->mUrlProtocols = wfUrlProtocols();
 +      public function __construct(
 +              array $parserConf = [], MagicWordFactory $magicWordFactory = null,
 +              Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
 +              SpecialPageFactory $spFactory = null, Config $siteConfig = null
 +      ) {
 +              $this->mConf = $parserConf;
 +              $this->mUrlProtocols = $urlProtocols ?? wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')' .
                        self::EXT_LINK_ADDR .
                        self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F\\x{FFFD}]*?)\]/Su';
 -              if ( isset( $conf['preprocessorClass'] ) ) {
 -                      $this->mPreprocessorClass = $conf['preprocessorClass'];
 -              } elseif ( defined( 'HPHP_VERSION' ) ) {
 -                      # Preprocessor_Hash is much faster than Preprocessor_DOM under HipHop
 +              if ( isset( $parserConf['preprocessorClass'] ) ) {
 +                      $this->mPreprocessorClass = $parserConf['preprocessorClass'];
 +              } elseif ( wfIsHHVM() ) {
 +                      # Under HHVM Preprocessor_Hash is much faster than Preprocessor_DOM
                        $this->mPreprocessorClass = Preprocessor_Hash::class;
                } elseif ( extension_loaded( 'domxml' ) ) {
                        # PECL extension that conflicts with the core DOM extension (T15770)
                        $this->mPreprocessorClass = Preprocessor_Hash::class;
                }
                wfDebug( __CLASS__ . ": using preprocessor: {$this->mPreprocessorClass}\n" );
 +
 +              $services = MediaWikiServices::getInstance();
 +              $this->magicWordFactory = $magicWordFactory ??
 +                      $services->getMagicWordFactory();
 +
 +              $this->contLang = $contLang ?? $services->getContentLanguage();
 +
 +              $this->factory = $factory ?? $services->getParserFactory();
 +              $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
 +              $this->siteConfig = $siteConfig ?? MediaWikiServices::getInstance()->getMainConfig();
        }
  
        /**
         * @private
         */
        public function clearState() {
 -              if ( $this->mFirstCall ) {
 -                      $this->firstCallInit();
 -              }
 +              $this->firstCallInit();
                $this->mOutput = new ParserOutput;
                $this->mOptions->registerWatcher( [ $this->mOutput, 'recordOption' ] );
                $this->mAutonumber = 0;
         * Do not call this function recursively.
         *
         * @param string $text Text we want to parse
 +       * @param-taint $text escapes_htmlnoent
         * @param Title $title
         * @param ParserOptions $options
         * @param bool $linestart
         * @param bool $clearState
 -       * @param int $revid Number to pass in {{REVISIONID}}
 +       * @param int|null $revid Number to pass in {{REVISIONID}}
         * @return ParserOutput A ParserOutput
 +       * @return-taint escaped
         */
        public function parse(
                $text, Title $title, ParserOptions $options,
                        || isset( $this->mDoubleUnderscores['notitleconvert'] )
                        || $this->mOutput->getDisplayTitle() !== false )
                ) {
 -                      $convruletitle = $this->getConverterLanguage()->getConvRuleTitle();
 +                      $convruletitle = $this->getTargetLanguage()->getConvRuleTitle();
                        if ( $convruletitle ) {
                                $this->mOutput->setTitleText( $convruletitle );
                        } else {
 -                              $titleText = $this->getConverterLanguage()->convertTitle( $title );
 +                              $titleText = $this->getTargetLanguage()->convertTitle( $title );
                                $this->mOutput->setTitleText( $titleText );
                        }
                }
                # with CSS (T37247)
                $class = $this->mOptions->getWrapOutputClass();
                if ( $class !== false && !$this->mOptions->getInterfaceMessage() ) {
 -                      $text = Html::rawElement( 'div', [ 'class' => $class ], $text );
 +                      $this->mOutput->addWrapperDivClass( $class );
                }
  
                $this->mOutput->setText( $text );
         * @return string
         */
        protected function makeLimitReport() {
 -              global $wgShowHostnames;
 -
                $maxIncludeSize = $this->mOptions->getMaxIncludeSize();
  
                $cpuTime = $this->mOutput->getTimeSinceStart( 'cpu' );
                Hooks::run( 'ParserLimitReportPrepare', [ $this, $this->mOutput ] );
  
                $limitReport = "NewPP limit report\n";
 -              if ( $wgShowHostnames ) {
 +              if ( $this->siteConfig->get( 'ShowHostnames' ) ) {
                        $limitReport .= 'Parsed by ' . wfHostname() . "\n";
                }
                $limitReport .= 'Cached time: ' . $this->mOutput->getCacheTime() . "\n";
                // Since we're not really outputting HTML, decode the entities and
                // then re-encode the things that need hiding inside HTML comments.
                $limitReport = htmlspecialchars_decode( $limitReport );
 -              // Run deprecated hook
 -              Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ], '1.22' );
  
                // Sanitize for comment. Note '‐' in the replacement is U+2010,
                // which looks much like the problematic '-'.
                // Add on template profiling data in human/machine readable way
                $dataByFunc = $this->mProfiler->getFunctionStats();
                uasort( $dataByFunc, function ( $a, $b ) {
 -                      return $a['real'] < $b['real']; // descending order
 +                      return $b['real'] <=> $a['real']; // descending order
                } );
                $profileReport = [];
                foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
                $this->mOutput->setLimitReportData( 'limitreport-timingprofile', $profileReport );
  
                // Add other cache related metadata
 -              if ( $wgShowHostnames ) {
 +              if ( $this->siteConfig->get( 'ShowHostnames' ) ) {
                        $this->mOutput->setLimitReportData( 'cachereport-origin', wfHostname() );
                }
                $this->mOutput->setLimitReportData( 'cachereport-timestamp',
         * $text are not expanded
         *
         * @param string $text Text extension wants to have parsed
 +       * @param-taint $text escapes_htmlnoent
         * @param bool|PPFrame $frame The frame to use for expanding any template variables
         * @return string UNSAFE half-parsed HTML
 +       * @return-taint escaped
         */
        public function recursiveTagParse( $text, $frame = false ) {
                // Avoid PHP 7.1 warning from passing $this by reference
         * @since 1.25
         *
         * @param string $text Text extension wants to have parsed
 +       * @param-taint $text escapes_htmlnoent
         * @param bool|PPFrame $frame The frame to use for expanding any template variables
         * @return string Fully parsed HTML
 +       * @return-taint escaped
         */
        public function recursiveTagParseFully( $text, $frame = false ) {
                $text = $this->recursiveTagParse( $text, $frame );
         * Also removes comments.
         * Do not call this function recursively.
         * @param string $text
 -       * @param Title $title
 +       * @param Title|null $title
         * @param ParserOptions $options
         * @param int|null $revid
         * @param bool|PPFrame $frame
        /**
         * Accessor/mutator for the Title object
         *
 -       * @param Title $x Title object or null to just get the current one
 +       * @param Title|null $x Title object or null to just get the current one
         * @return Title
         */
        public function Title( $x = null ) {
        /**
         * Accessor/mutator for the ParserOptions object
         *
 -       * @param ParserOptions $x New value or null to just get the current one
 +       * @param ParserOptions|null $x New value or null to just get the current one
         * @return ParserOptions Current ParserOptions object
         */
        public function Options( $x = null ) {
  
        /**
         * Get the language object for language conversion
 +       * @deprecated since 1.32, just use getTargetLanguage()
         * @return Language|null
         */
        public function getConverterLanguage() {
                return $this->mLinkRenderer;
        }
  
 +      /**
 +       * Get the MagicWordFactory that this Parser is using
 +       *
 +       * @since 1.32
 +       * @return MagicWordFactory
 +       */
 +      public function getMagicWordFactory() {
 +              return $this->magicWordFactory;
 +      }
 +
 +      /**
 +       * Get the content language that this Parser is using
 +       *
 +       * @since 1.32
 +       * @return Language
 +       */
 +      public function getContentLanguage() {
 +              return $this->contLang;
 +      }
 +
        /**
         * Replaces all occurrences of HTML-style comments and the given tags
         * in the text with a random marker and returns the next text. The output
                                        $line = "</{$last_tag}>{$line}";
                                }
                                array_pop( $tr_attributes );
 -                              $outLine = $line . str_repeat( '</dd></dl>', $indent_level );
 +                              if ( $indent_level > 0 ) {
 +                                      $outLine = rtrim( $line ) . str_repeat( '</dd></dl>', $indent_level );
 +                              } else {
 +                                      $outLine = $line;
 +                              }
                        } elseif ( $first_two === '|-' ) {
                                # Now we have a table row
                                $line = preg_replace( '#^\|-+#', '', $line );
                                        # be mistaken as delimiting cell parameters
                                        # Bug T153140: Neither should language converter markup.
                                        if ( preg_match( '/\[\[|-\{/', $cell_data[0] ) === 1 ) {
 -                                              $cell = "{$previous}<{$last_tag}>{$cell}";
 +                                              $cell = "{$previous}<{$last_tag}>" . trim( $cell );
                                        } elseif ( count( $cell_data ) == 1 ) {
 -                                              $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
 +                                              // Whitespace in cells is trimmed
 +                                              $cell = "{$previous}<{$last_tag}>" . trim( $cell_data[0] );
                                        } else {
                                                $attributes = $this->mStripState->unstripBoth( $cell_data[0] );
                                                $attributes = Sanitizer::fixTagAttributes( $attributes, $last_tag );
 -                                              $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
 +                                              // Whitespace in cells is trimmed
 +                                              $cell = "{$previous}<{$last_tag}{$attributes}>" . trim( $cell_data[1] );
                                        }
  
                                        $outLine .= $cell;
         * @private
         *
         * @param string $text The text to parse
 +       * @param-taint $text escapes_html
         * @param bool $isMain Whether this is being called from the main parse() function
         * @param PPFrame|bool $frame A pre-processor frame
         *
                }
  
                # Clean up special characters, only run once, next-to-last before doBlockLevels
 -              $fixtags = [
 -                      # French spaces, last one Guillemet-left
 -                      # only if there is something before the space
 -                      '/(.) (?=\\?|:|;|!|%|\\302\\273)/' => '\\1&#160;',
 -                      # french spaces, Guillemet-right
 -                      '/(\\302\\253) /' => '\\1&#160;',
 -                      '/&#160;(!\s*important)/' => ' \\1', # Beware of CSS magic word !important, T13874.
 -              ];
 -              $text = preg_replace( array_keys( $fixtags ), array_values( $fixtags ), $text );
 +              $text = Sanitizer::armorFrenchSpaces( $text );
  
                $text = $this->doBlockLevels( $text, $linestart );
  
                                # The position of the convert() call should not be changed. it
                                # assumes that the links are all replaced and the only thing left
                                # is the <nowiki> mark.
 -                              $text = $this->getConverterLanguage()->convert( $text );
 +                              $text = $this->getTargetLanguage()->convert( $text );
                        }
                }
  
                } else {
                        # attempt to sanitize at least some nesting problems
                        # (T4702 and quite a few others)
 +                      # This code path is buggy and deprecated!
 +                      wfDeprecated( 'disabling tidy', '1.33' );
                        $tidyregs = [
                                # ''Something [http://www.cool.com cool''] -->
                                # <i>Something</i><a href="http://www.cool.com"..><i>cool></i></a>
        /**
         * @throws MWException
         * @param array $m
 -       * @return HTML|string
 +       * @return string HTML
         */
        public function magicLinkCallback( $m ) {
                if ( isset( $m[1] ) && $m[1] !== '' ) {
                if ( $text === false ) {
                        # Not an image, make a link
                        $text = Linker::makeExternalLink( $url,
 -                              $this->getConverterLanguage()->markNoConversion( $url, true ),
 +                              $this->getTargetLanguage()->getConverter()->markNoConversion( $url ),
                                true, 'free',
                                $this->getExternalLinkAttribs( $url ), $this->mTitle );
                        # Register it in the output object...
        public function doHeadings( $text ) {
                for ( $i = 6; $i >= 1; --$i ) {
                        $h = str_repeat( '=', $i );
 -                      $text = preg_replace( "/^$h(.+)$h\\s*$/m", "<h$i>\\1</h$i>", $text );
 +                      // Trim non-newline whitespace from headings
 +                      // Using \s* will break for: "==\n===\n" and parse as <h2>=</h2>
 +                      $text = preg_replace( "/^(?:$h)[ \\t]*(.+?)[ \\t]*(?:$h)\\s*$/m", "<h$i>\\1</h$i>", $text );
                }
                return $text;
        }
  
                        $dtrail = '';
  
 -                      # Set linktype for CSS - if URL==text, link is essentially free
 -                      $linktype = ( $text === $url ) ? 'free' : 'text';
 +                      # Set linktype for CSS
 +                      $linktype = 'text';
  
                        # No link text, e.g. [http://domain.tld/some.link]
                        if ( $text == '' ) {
                                list( $dtrail, $trail ) = Linker::splitTrail( $trail );
                        }
  
 -                      $text = $this->getConverterLanguage()->markNoConversion( $text );
 +                      // Excluding protocol-relative URLs may avoid many false positives.
 +                      if ( preg_match( '/^(?:' . wfUrlProtocolsWithoutProtRel() . ')/', $text ) ) {
 +                              $text = $this->getTargetLanguage()->getConverter()->markNoConversion( $text );
 +                      }
  
                        $url = Sanitizer::cleanUrl( $url );
  
         * @since 1.21
         * @param string|bool $url Optional URL, to extract the domain from for rel =>
         *   nofollow if appropriate
 -       * @param Title $title Optional Title, for wgNoFollowNsExceptions lookups
 +       * @param Title|null $title Optional Title, for wgNoFollowNsExceptions lookups
         * @return string|null Rel attribute for $url
         */
        public static function getExternalLinkRel( $url = false, $title = null ) {
         * @return string
         */
        public static function normalizeLinkUrl( $url ) {
 -              # First, make sure unsafe characters are encoded
 +              # Test for RFC 3986 IPv6 syntax
 +              $scheme = '[a-z][a-z0-9+.-]*:';
 +              $userinfo = '(?:[a-z0-9\-._~!$&\'()*+,;=:]|%[0-9a-f]{2})*';
 +              $ipv6Host = '\\[((?:[0-9a-f:]|%3[0-A]|%[46][1-6])+)\\]';
 +              if ( preg_match( "<^(?:{$scheme})?//(?:{$userinfo}@)?{$ipv6Host}(?:[:/?#].*|)$>i", $url, $m ) &&
 +                      IP::isValid( rawurldecode( $m[1] ) )
 +              ) {
 +                      $isIPv6 = rawurldecode( $m[1] );
 +              } else {
 +                      $isIPv6 = false;
 +              }
 +
 +              # Make sure unsafe characters are encoded
                $url = preg_replace_callback( '/[\x00-\x20"<>\[\\\\\]^`{|}\x7F-\xFF]/',
                        function ( $m ) {
                                return rawurlencode( $m[0] );
                $ret = self::normalizeUrlComponent(
                        substr( $url, 0, $end ), '"#%<>[\]^`{|}/?' ) . $ret;
  
 +              # Fix IPv6 syntax
 +              if ( $isIPv6 !== false ) {
 +                      $ipv6Host = "%5B({$isIPv6})%5D";
 +                      $ret = preg_replace(
 +                              "<^((?:{$scheme})?//(?:{$userinfo}@)?){$ipv6Host}(?=[:/?#]|$)>i",
 +                              "$1[$2]",
 +                              $ret
 +                      );
 +              }
 +
                return $ret;
        }
  
         * @private
         */
        public function replaceInternalLinks2( &$s ) {
 -              global $wgExtraInterlanguageLinkPrefixes;
 -
                static $tc = false, $e1, $e1_img;
                # the % is needed to support urlencoded titles as well
                if ( !$tc ) {
                if ( $useLinkPrefixExtension ) {
                        # Match the end of a line for a word that's not followed by whitespace,
                        # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
 -                      global $wgContLang;
 -                      $charset = $wgContLang->linkPrefixCharset();
 +                      $charset = $this->contLang->linkPrefixCharset();
                        $e2 = "/^((?>.*[^$charset]|))(.+)$/sDu";
                }
  
                                if (
                                        $iw && $this->mOptions->getInterwikiMagic() && $nottalk && (
                                                Language::fetchLanguageName( $iw, null, 'mw' ) ||
 -                                              in_array( $iw, $wgExtraInterlanguageLinkPrefixes )
 +                                              in_array( $iw, $this->siteConfig->get( 'ExtraInterlanguageLinkPrefixes' ) )
                                        )
                                ) {
                                        # T26502: filter duplicates
                                        }
                                        $sortkey = Sanitizer::decodeCharReferences( $sortkey );
                                        $sortkey = str_replace( "\n", '', $sortkey );
 -                                      $sortkey = $this->getConverterLanguage()->convertCategoryKey( $sortkey );
 +                                      $sortkey = $this->getTargetLanguage()->convertCategoryKey( $sortkey );
                                        $this->mOutput->addCategory( $nt->getDBkey(), $sortkey );
  
                                        continue;
         *
         * @private
         *
 -       * @param string $index Magic variable identifier as mapped in MagicWord::$mVariableIDs
 +       * @param string $index Magic variable identifier as mapped in MagicWordFactory::$mVariableIDs
         * @param bool|PPFrame $frame
         *
         * @throws MWException
         * @return string
         */
        public function getVariableValue( $index, $frame = false ) {
 -              global $wgContLang, $wgSitename, $wgServer, $wgServerName;
 -              global $wgArticlePath, $wgScriptPath, $wgStylePath;
 -
                if ( is_null( $this->mTitle ) ) {
                        // If no title set, bad things are going to happen
                        // later. Title should always be set since this
                                        $this->mOutput->setFlag( 'vary-revision' );
                                        wfDebug( __METHOD__ . ": {{PAGEID}} used in a new page, setting vary-revision...\n" );
                                }
 -                              $value = $pageid ? $pageid : null;
 +                              $value = $pageid ?: null;
                                break;
                        case 'revisionid':
                                # Let the edit saving system know we should parse the page
                                $this->mOutput->setFlag( 'vary-revision-id' );
                                wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-id...\n" );
                                $value = $this->mRevisionId;
 -                              if ( !$value && $this->mOptions->getSpeculativeRevIdCallback() ) {
 -                                      $value = call_user_func( $this->mOptions->getSpeculativeRevIdCallback() );
 -                                      $this->mOutput->setSpeculativeRevIdUsed( $value );
 +
 +                              if ( !$value ) {
 +                                      $rev = $this->getRevisionObject();
 +                                      if ( $rev ) {
 +                                              $value = $rev->getId();
 +                                      }
 +                              }
 +
 +                              if ( !$value ) {
 +                                      $value = $this->mOptions->getSpeculativeRevId();
 +                                      if ( $value ) {
 +                                              $this->mOutput->setSpeculativeRevIdUsed( $value );
 +                                      }
                                }
                                break;
                        case 'revisionday':
 -                              # Let the edit saving system know we should parse the page
 -                              # *after* a revision ID has been assigned. This is for null edits.
 -                              $this->mOutput->setFlag( 'vary-revision' );
 -                              wfDebug( __METHOD__ . ": {{REVISIONDAY}} used, setting vary-revision...\n" );
 -                              $value = intval( substr( $this->getRevisionTimestamp(), 6, 2 ) );
 +                              $value = (int)$this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionday2':
 -                              # Let the edit saving system know we should parse the page
 -                              # *after* a revision ID has been assigned. This is for null edits.
 -                              $this->mOutput->setFlag( 'vary-revision' );
 -                              wfDebug( __METHOD__ . ": {{REVISIONDAY2}} used, setting vary-revision...\n" );
 -                              $value = substr( $this->getRevisionTimestamp(), 6, 2 );
 +                              $value = $this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionmonth':
 -                              # Let the edit saving system know we should parse the page
 -                              # *after* a revision ID has been assigned. This is for null edits.
 -                              $this->mOutput->setFlag( 'vary-revision' );
 -                              wfDebug( __METHOD__ . ": {{REVISIONMONTH}} used, setting vary-revision...\n" );
 -                              $value = substr( $this->getRevisionTimestamp(), 4, 2 );
 +                              $value = $this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionmonth1':
 -                              # Let the edit saving system know we should parse the page
 -                              # *after* a revision ID has been assigned. This is for null edits.
 -                              $this->mOutput->setFlag( 'vary-revision' );
 -                              wfDebug( __METHOD__ . ": {{REVISIONMONTH1}} used, setting vary-revision...\n" );
 -                              $value = intval( substr( $this->getRevisionTimestamp(), 4, 2 ) );
 +                              $value = (int)$this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
                                break;
                        case 'revisionyear':
 -                              # Let the edit saving system know we should parse the page
 -                              # *after* a revision ID has been assigned. This is for null edits.
 -                              $this->mOutput->setFlag( 'vary-revision' );
 -                              wfDebug( __METHOD__ . ": {{REVISIONYEAR}} used, setting vary-revision...\n" );
 -                              $value = substr( $this->getRevisionTimestamp(), 0, 4 );
 +                              $value = $this->getRevisionTimestampSubstring( 0, 4, self::MAX_TTS, $index );
                                break;
                        case 'revisiontimestamp':
                                # Let the edit saving system know we should parse the page
                                $value = $this->getRevisionSize();
                                break;
                        case 'namespace':
 -                              $value = str_replace( '_', ' ', $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
 +                              $value = str_replace( '_', ' ',
 +                                      $this->contLang->getNsText( $this->mTitle->getNamespace() ) );
                                break;
                        case 'namespacee':
 -                              $value = wfUrlencode( $wgContLang->getNsText( $this->mTitle->getNamespace() ) );
 +                              $value = wfUrlencode( $this->contLang->getNsText( $this->mTitle->getNamespace() ) );
                                break;
                        case 'namespacenumber':
                                $value = $this->mTitle->getNamespace();
                                $value = SpecialVersion::getVersion();
                                break;
                        case 'articlepath':
 -                              return $wgArticlePath;
 +                              return $this->siteConfig->get( 'ArticlePath' );
                        case 'sitename':
 -                              return $wgSitename;
 +                              return $this->siteConfig->get( 'Sitename' );
                        case 'server':
 -                              return $wgServer;
 +                              return $this->siteConfig->get( 'Server' );
                        case 'servername':
 -                              return $wgServerName;
 +                              return $this->siteConfig->get( 'ServerName' );
                        case 'scriptpath':
 -                              return $wgScriptPath;
 +                              return $this->siteConfig->get( 'ScriptPath' );
                        case 'stylepath':
 -                              return $wgStylePath;
 +                              return $this->siteConfig->get( 'StylePath' );
                        case 'directionmark':
                                return $pageLang->getDirMark();
                        case 'contentlanguage':
 -                              global $wgLanguageCode;
 -                              return $wgLanguageCode;
 +                              return $this->siteConfig->get( 'LanguageCode' );
                        case 'pagelanguage':
                                $value = $pageLang->getCode();
                                break;
                return $value;
        }
  
 +      /**
 +       * @param int $start
 +       * @param int $len
 +       * @param int $mtts Max time-till-save; sets vary-revision if result might change by then
 +       * @param string $variable Parser variable name
 +       * @return string
 +       */
 +      private function getRevisionTimestampSubstring( $start, $len, $mtts, $variable ) {
 +              # Get the timezone-adjusted timestamp to be used for this revision
 +              $resNow = substr( $this->getRevisionTimestamp(), $start, $len );
 +              # Possibly set vary-revision if there is not yet an associated revision
 +              if ( !$this->getRevisionObject() ) {
 +                      # Get the timezone-adjusted timestamp $mtts seconds in the future
 +                      $resThen = substr(
 +                              $this->contLang->userAdjust( wfTimestamp( TS_MW, time() + $mtts ), '' ),
 +                              $start,
 +                              $len
 +                      );
 +
 +                      if ( $resNow !== $resThen ) {
 +                              # Let the edit saving system know we should parse the page
 +                              # *after* a revision ID has been assigned. This is for null edits.
 +                              $this->mOutput->setFlag( 'vary-revision' );
 +                              wfDebug( __METHOD__ . ": $variable used, setting vary-revision...\n" );
 +                      }
 +              }
 +
 +              return $resNow;
 +      }
 +
        /**
         * initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers
         *
         * @private
         */
        public function initialiseVariables() {
 -              $variableIDs = MagicWord::getVariableIDs();
 -              $substIDs = MagicWord::getSubstIDs();
 +              $variableIDs = $this->magicWordFactory->getVariableIDs();
 +              $substIDs = $this->magicWordFactory->getSubstIDs();
  
 -              $this->mVariables = new MagicWordArray( $variableIDs );
 -              $this->mSubstWords = new MagicWordArray( $substIDs );
 +              $this->mVariables = $this->magicWordFactory->newArray( $variableIDs );
 +              $this->mSubstWords = $this->magicWordFactory->newArray( $substIDs );
        }
  
        /**
         *       'expansion-depth-exceeded-category')
         * @param string|int|null $current Current value
         * @param string|int|null $max Maximum allowed, when an explicit limit has been
 -       *       exceeded, provide the values (optional)
 +       *       exceeded, provide the values (optional)
         */
        public function limitationWarn( $limitationType, $current = '', $max = '' ) {
                # does no harm if $current and $max are present but are unnecessary for the message
                        $id = $this->mVariables->matchStartToEnd( $part1 );
                        if ( $id !== false ) {
                                $text = $this->getVariableValue( $id, $frame );
 -                              if ( MagicWord::getCacheTTL( $id ) > -1 ) {
 -                                      $this->mOutput->updateCacheExpiry( MagicWord::getCacheTTL( $id ) );
 +                              if ( $this->magicWordFactory->getCacheTTL( $id ) > -1 ) {
 +                                      $this->mOutput->updateCacheExpiry(
 +                                              $this->magicWordFactory->getCacheTTL( $id ) );
                                }
                                $found = true;
                        }
                # MSG, MSGNW and RAW
                if ( !$found ) {
                        # Check for MSGNW:
 -                      $mwMsgnw = MagicWord::get( 'msgnw' );
 +                      $mwMsgnw = $this->magicWordFactory->get( 'msgnw' );
                        if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
                                $nowiki = true;
                        } else {
                                # Remove obsolete MSG:
 -                              $mwMsg = MagicWord::get( 'msg' );
 +                              $mwMsg = $this->magicWordFactory->get( 'msg' );
                                $mwMsg->matchStartAndRemove( $part1 );
                        }
  
                        # Check for RAW:
 -                      $mwRaw = MagicWord::get( 'raw' );
 +                      $mwRaw = $this->magicWordFactory->get( 'raw' );
                        if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
                                $forceRawInterwiki = true;
                        }
                                for ( $i = 0; $i < $argsLength; $i++ ) {
                                        $funcArgs[] = $args->item( $i );
                                }
 -                              try {
 -                                      $result = $this->callParserFunction( $frame, $func, $funcArgs );
 -                              } catch ( Exception $ex ) {
 -                                      throw $ex;
 -                              }
 +
 +                              $result = $this->callParserFunction( $frame, $func, $funcArgs );
  
                                // Extract any forwarded flags
                                if ( isset( $result['title'] ) ) {
                        if ( $title ) {
                                $titleText = $title->getPrefixedText();
                                # Check for language variants if the template is not found
 -                              if ( $this->getConverterLanguage()->hasVariants() && $title->getArticleID() == 0 ) {
 -                                      $this->getConverterLanguage()->findVariantLink( $part1, $title, true );
 +                              if ( $this->getTargetLanguage()->hasVariants() && $title->getArticleID() == 0 ) {
 +                                      $this->getTargetLanguage()->findVariantLink( $part1, $title, true );
                                }
                                # Do recursion depth check
                                $limit = $this->mOptions->getMaxTemplateDepth();
                                        && $this->mOptions->getAllowSpecialInclusion()
                                        && $this->ot['html']
                                ) {
 -                                      $specialPage = SpecialPageFactory::getPage( $title->getDBkey() );
 +                                      $specialPage = $this->specialPageFactory->getPage( $title->getDBkey() );
                                        // Pass the template arguments as URL parameters.
                                        // "uselang" will have no effect since the Language object
                                        // is forced to the one defined in ParserOptions.
                                                $context->setUser( User::newFromName( '127.0.0.1', false ) );
                                        }
                                        $context->setLanguage( $this->mOptions->getUserLangObj() );
 -                                      $ret = SpecialPageFactory::capturePath(
 -                                              $title, $context, $this->getLinkRenderer() );
 +                                      $ret = $this->specialPageFactory->capturePath( $title, $context, $this->getLinkRenderer() );
                                        if ( $ret ) {
                                                $text = $context->getOutput()->getHTML();
                                                $this->mOutput->addOutputPageMetadata( $context->getOutput() );
         * @return array
         */
        public function callParserFunction( $frame, $function, array $args = [] ) {
 -              global $wgContLang;
 -
                # Case sensitive functions
                if ( isset( $this->mFunctionSynonyms[1][$function] ) ) {
                        $function = $this->mFunctionSynonyms[1][$function];
                } else {
                        # Case insensitive functions
 -                      $function = $wgContLang->lc( $function );
 +                      $function = $this->contLang->lc( $function );
                        if ( isset( $this->mFunctionSynonyms[0][$function] ) ) {
                                $function = $this->mFunctionSynonyms[0][$function];
                        } else {
                        }
                }
  
 -              $result = call_user_func_array( $callback, $allArgs );
 +              $result = $callback( ...$allArgs );
  
                # The interface for function hooks allows them to return a wikitext
                # string or an array containing the string and any flags. This mungs
                if ( is_string( $stuff['text'] ) ) {
                        $text = strtr( $text, "\x7f", "?" );
                }
 -              $finalTitle = isset( $stuff['finalTitle'] ) ? $stuff['finalTitle'] : $title;
 +              $finalTitle = $stuff['finalTitle'] ?? $title;
                if ( isset( $stuff['deps'] ) ) {
                        foreach ( $stuff['deps'] as $dep ) {
                                $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
                        $rev_id = $rev ? $rev->getId() : 0;
                        # If there is no current revision, there is no page
                        if ( $id === false && !$rev ) {
 -                              $linkCache = LinkCache::singleton();
 +                              $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                                $linkCache->addBadLinkObj( $title );
                        }
  
                                        break;
                                }
                        } elseif ( $title->getNamespace() == NS_MEDIAWIKI ) {
 -                              global $wgContLang;
 -                              $message = wfMessage( $wgContLang->lcfirst( $title->getText() ) )->inContentLanguage();
 +                              $message = wfMessage( MediaWikiServices::getInstance()->getContentLanguage()->
 +                                      lcfirst( $title->getText() ) )->inContentLanguage();
                                if ( !$message->exists() ) {
                                        $text = false;
                                        break;
         * @param Title $title
         * @param array $options Array of options to RepoGroup::findFile
         * @return File|bool
 +       * @deprecated since 1.32, use fetchFileAndTitle instead
         */
        public function fetchFile( $title, $options = [] ) {
 +              wfDeprecated( __METHOD__, '1.32' );
                return $this->fetchFileAndTitle( $title, $options )[0];
        }
  
         * Transclude an interwiki link.
         *
         * @param Title $title
 -       * @param string $action
 +       * @param string $action Usually one of (raw, render)
         *
         * @return string
         */
        public function interwikiTransclude( $title, $action ) {
 -              global $wgEnableScaryTranscluding;
 -
 -              if ( !$wgEnableScaryTranscluding ) {
 +              if ( !$this->siteConfig->get( 'EnableScaryTranscluding' ) ) {
                        return wfMessage( 'scarytranscludedisabled' )->inContentLanguage()->text();
                }
  
                $url = $title->getFullURL( [ 'action' => $action ] );
 -
 -              if ( strlen( $url ) > 255 ) {
 +              if ( strlen( $url ) > 1024 ) {
                        return wfMessage( 'scarytranscludetoolong' )->inContentLanguage()->text();
                }
 -              return $this->fetchScaryTemplateMaybeFromCache( $url );
 -      }
  
 -      /**
 -       * @param string $url
 -       * @return mixed|string
 -       */
 -      public function fetchScaryTemplateMaybeFromCache( $url ) {
 -              global $wgTranscludeCacheExpiry;
 -              $dbr = wfGetDB( DB_REPLICA );
 -              $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
 -              $obj = $dbr->selectRow( 'transcache', [ 'tc_time', 'tc_contents' ],
 -                              [ 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ] );
 -              if ( $obj ) {
 -                      return $obj->tc_contents;
 -              }
 -
 -              $req = MWHttpRequest::factory( $url, [], __METHOD__ );
 -              $status = $req->execute(); // Status object
 -              if ( $status->isOK() ) {
 -                      $text = $req->getContent();
 -              } elseif ( $req->getStatus() != 200 ) {
 +              $wikiId = $title->getTransWikiID(); // remote wiki ID or false
 +
 +              $fname = __METHOD__;
 +              $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
 +
 +              $data = $cache->getWithSetCallback(
 +                      $cache->makeGlobalKey(
 +                              'interwiki-transclude',
 +                              ( $wikiId !== false ) ? $wikiId : 'external',
 +                              sha1( $url )
 +                      ),
 +                      $this->siteConfig->get( 'TranscludeCacheExpiry' ),
 +                      function ( $oldValue, &$ttl ) use ( $url, $fname, $cache ) {
 +                              $req = MWHttpRequest::factory( $url, [], $fname );
 +
 +                              $status = $req->execute(); // Status object
 +                              if ( !$status->isOK() ) {
 +                                      $ttl = $cache::TTL_UNCACHEABLE;
 +                              } elseif ( $req->getResponseHeader( 'X-Database-Lagged' ) !== null ) {
 +                                      $ttl = min( $cache::TTL_LAGGED, $ttl );
 +                              }
 +
 +                              return [
 +                                      'text' => $status->isOK() ? $req->getContent() : null,
 +                                      'code' => $req->getStatus()
 +                              ];
 +                      },
 +                      [
 +                              'checkKeys' => ( $wikiId !== false )
 +                                      ? [ $cache->makeGlobalKey( 'interwiki-page', $wikiId, $title->getDBkey() ) ]
 +                                      : [],
 +                              'pcGroup' => 'interwiki-transclude:5',
 +                              'pcTTL' => $cache::TTL_PROC_LONG
 +                      ]
 +              );
 +
 +              if ( is_string( $data['text'] ) ) {
 +                      $text = $data['text'];
 +              } elseif ( $data['code'] != 200 ) {
                        // Though we failed to fetch the content, this status is useless.
 -                      return wfMessage( 'scarytranscludefailed-httpstatus' )
 -                              ->params( $url, $req->getStatus() /* HTTP status */ )->inContentLanguage()->text();
 +                      $text = wfMessage( 'scarytranscludefailed-httpstatus' )
 +                              ->params( $url, $data['code'] )->inContentLanguage()->text();
                } else {
 -                      return wfMessage( 'scarytranscludefailed', $url )->inContentLanguage()->text();
 +                      $text = wfMessage( 'scarytranscludefailed', $url )->inContentLanguage()->text();
                }
  
 -              $dbw = wfGetDB( DB_MASTER );
 -              $dbw->replace( 'transcache', [ 'tc_url' ], [
 -                      'tc_url' => $url,
 -                      'tc_time' => $dbw->timestamp( time() ),
 -                      'tc_contents' => $text
 -              ] );
                return $text;
        }
  
         */
        public function doDoubleUnderscore( $text ) {
                # The position of __TOC__ needs to be recorded
 -              $mw = MagicWord::get( 'toc' );
 +              $mw = $this->magicWordFactory->get( 'toc' );
                if ( $mw->match( $text ) ) {
                        $this->mShowToc = true;
                        $this->mForceTocPosition = true;
                }
  
                # Now match and remove the rest of them
 -              $mwa = MagicWord::getDoubleUnderscoreArray();
 +              $mwa = $this->magicWordFactory->getDoubleUnderscoreArray();
                $this->mDoubleUnderscores = $mwa->matchAndRemove( $text );
  
                if ( isset( $this->mDoubleUnderscores['nogallery'] ) ) {
         * @private
         */
        public function formatHeadings( $text, $origText, $isMain = true ) {
 -              global $wgMaxTocLevel;
 -
                # Inhibit editsection links if requested in the page
                if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
                        $maybeShowEditLink = false;
  
                # Get all headlines for numbering them and adding funky stuff like [edit]
                # links - this is for later, but we need the number of headlines right now
 +              # NOTE: white space in headings have been trimmed in doHeadings. They shouldn't
 +              # be trimmed here since whitespace in HTML headings is significant.
                $matches = [];
                $numMatches = preg_match_all(
 -                      '/<H(?P<level>[1-6])(?P<attrib>.*?>)\s*(?P<header>[\s\S]*?)\s*<\/H[1-6] *>/i',
 +                      '/<H(?P<level>[1-6])(?P<attrib>.*?>)(?P<header>[\s\S]*?)<\/H[1-6] *>/i',
                        $text,
                        $matches
                );
  
                $headlines = $numMatches !== false ? $matches[3] : [];
  
 +              $maxTocLevel = $this->siteConfig->get( 'MaxTocLevel' );
                foreach ( $headlines as $headline ) {
                        $isTemplate = false;
                        $titleText = false;
                                # Increase TOC level
                                $toclevel++;
                                $sublevelCount[$toclevel] = 0;
 -                              if ( $toclevel < $wgMaxTocLevel ) {
 +                              if ( $toclevel < $maxTocLevel ) {
                                        $prevtoclevel = $toclevel;
                                        $toc .= Linker::tocIndent();
                                        $numVisible++;
                                if ( $i == 0 ) {
                                        $toclevel = 1;
                                }
 -                              if ( $toclevel < $wgMaxTocLevel ) {
 -                                      if ( $prevtoclevel < $wgMaxTocLevel ) {
 +                              if ( $toclevel < $maxTocLevel ) {
 +                                      if ( $prevtoclevel < $maxTocLevel ) {
                                                # Unindent only if the previous toc level was shown :p
                                                $toc .= Linker::tocUnindent( $prevtoclevel - $toclevel );
                                                $prevtoclevel = $toclevel;
                                }
                        } else {
                                # No change in level, end TOC line
 -                              if ( $toclevel < $wgMaxTocLevel ) {
 +                              if ( $toclevel < $maxTocLevel ) {
                                        $toc .= Linker::tocLineEnd();
                                }
                        }
                        # Avoid insertion of weird stuff like <math> by expanding the relevant sections
                        $safeHeadline = $this->mStripState->unstripBoth( $safeHeadline );
  
 +                      # Remove any <style> or <script> tags (T198618)
 +                      $safeHeadline = preg_replace(
 +                              '#<(style|script)(?: [^>]*[^>/])?>.*?</\1>#is',
 +                              '',
 +                              $safeHeadline
 +                      );
 +
                        # Strip out HTML (first regex removes any tag not allowed)
                        # Allowed tags are:
                        # * <sup> and <sub> (T10393)
                                ) . ' ' . $headline;
                        }
  
 -                      if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
 +                      if ( $enoughToc && ( !isset( $maxTocLevel ) || $toclevel < $maxTocLevel ) ) {
                                $toc .= Linker::tocLine( $linkAnchor, $tocline,
                                        $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
                        }
                }
  
                if ( $enoughToc ) {
 -                      if ( $prevtoclevel > 0 && $prevtoclevel < $wgMaxTocLevel ) {
 +                      if ( $prevtoclevel > 0 && $prevtoclevel < $maxTocLevel ) {
                                $toc .= Linker::tocUnindent( $prevtoclevel - 1 );
                        }
                        $toc = Linker::tocList( $toc, $this->mOptions->getUserLangObj() );
         * @return string
         */
        private function pstPass2( $text, $user ) {
 -              global $wgContLang;
 -
 -              # Note: This is the timestamp saved as hardcoded wikitext to
 -              # the database, we use $wgContLang here in order to give
 -              # everyone the same signature and use the default one rather
 -              # than the one selected in each user's preferences.
 -              # (see also T14815)
 +              # Note: This is the timestamp saved as hardcoded wikitext to the database, we use
 +              # $this->contLang here in order to give everyone the same signature and use the default one
 +              # rather than the one selected in each user's preferences.  (see also T14815)
                $ts = $this->mOptions->getTimestamp();
                $timestamp = MWTimestamp::getLocalInstance( $ts );
                $ts = $timestamp->format( 'YmdHis' );
                $tzMsg = $timestamp->getTimezoneMessage()->inContentLanguage()->text();
  
 -              $d = $wgContLang->timeanddate( $ts, false, false ) . " ($tzMsg)";
 +              $d = $this->contLang->timeanddate( $ts, false, false ) . " ($tzMsg)";
  
                # Variable replacement
                # Because mOutputType is OT_WIKI, this will only process {{subst:xxx}} type tags
         * @return string
         */
        public function getUserSig( &$user, $nickname = false, $fancySig = null ) {
 -              global $wgMaxSigChars;
 -
                $username = $user->getName();
  
                # If not given, retrieve from the user object.
  
                $nickname = $nickname == null ? $username : $nickname;
  
 -              if ( mb_strlen( $nickname ) > $wgMaxSigChars ) {
 +              if ( mb_strlen( $nickname ) > $this->siteConfig->get( 'MaxSigChars' ) ) {
                        $nickname = $username;
                        wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
                } elseif ( $fancySig !== false ) {
  
                # @todo FIXME: Regex doesn't respect extension tags or nowiki
                #  => Move this logic to braceSubstitution()
 -              $substWord = MagicWord::get( 'subst' );
 +              $substWord = $this->magicWordFactory->get( 'subst' );
                $substRegex = '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase();
                $substText = '{{' . $substWord->getSynonym( 0 );
  
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
                }
 -              $oldVal = isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null;
 +              $oldVal = $this->mTagHooks[$tag] ?? null;
                $this->mTagHooks[$tag] = $callback;
                if ( !in_array( $tag, $this->mStripList ) ) {
                        $this->mStripList[] = $tag;
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
                }
 -              $oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
 +              $oldVal = $this->mTransparentTagHooks[$tag] ?? null;
                $this->mTransparentTagHooks[$tag] = $callback;
  
                return $oldVal;
         * @return string|callable The old callback function for this name, if any
         */
        public function setFunctionHook( $id, callable $callback, $flags = 0 ) {
 -              global $wgContLang;
 -
                $oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null;
                $this->mFunctionHooks[$id] = [ $callback, $flags ];
  
                # Add to function cache
 -              $mw = MagicWord::get( $id );
 +              $mw = $this->magicWordFactory->get( $id );
                if ( !$mw ) {
                        throw new MWException( __METHOD__ . '() expecting a magic word identifier.' );
                }
                foreach ( $synonyms as $syn ) {
                        # Case
                        if ( !$sensitive ) {
 -                              $syn = $wgContLang->lc( $syn );
 +                              $syn = $this->contLang->lc( $syn );
                        }
                        # Add leading hash
                        if ( !( $flags & self::SFH_NO_HASH ) ) {
         * @return array
         */
        public function getFunctionHooks() {
 +              $this->firstCallInit();
                return array_keys( $this->mFunctionHooks );
        }
  
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
                }
 -              $old = isset( $this->mFunctionTagHooks[$tag] ) ?
 -                      $this->mFunctionTagHooks[$tag] : null;
 +              $old = $this->mFunctionTagHooks[$tag] ?? null;
                $this->mFunctionTagHooks[$tag] = [ $callback, $flags ];
  
                if ( !in_array( $tag, $this->mStripList ) ) {
                        $ig->setShowFilename( false );
                }
                if ( isset( $params['caption'] ) ) {
-                       $caption = $params['caption'];
-                       $caption = htmlspecialchars( $caption );
-                       $caption = $this->replaceInternalLinks( $caption );
+                       // NOTE: We aren't passing a frame here or below.  Frame info
+                       // is currently opaque to Parsoid, which acts on OT_PREPROCESS.
+                       // See T107332#4030581
+                       $caption = $this->recursiveTagParse( $params['caption'] );
                        $ig->setCaptionHtml( $caption );
                }
                if ( isset( $params['perrow'] ) ) {
                                unset( $paramMap['img_width'] );
                        }
  
 -                      $mwArray = new MagicWordArray( array_keys( $paramMap ) );
 +                      $mwArray = $this->magicWordFactory->newArray( array_keys( $paramMap ) );
  
                        $label = '';
                        $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.
 +                                                              $linkValue = $this->stripAltText( $match, false );
                                                                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();
 -                                                                      }
 +                                                              list( $type, $target ) = $this->parseLinkParameter( $linkValue );
 +                                                              if ( $type === 'link-url' ) {
 +                                                                      $link = $target;
 +                                                                      $this->mOutput->addExternalLink( $target );
 +                                                              } elseif ( $type === 'link-title' ) {
 +                                                                      $link = $target->getLinkURL();
 +                                                                      $this->mOutput->addLink( $target );
                                                                }
                                                                break;
                                                        default:
                                                                } else {
                                                                        // Guess not, consider it as caption.
                                                                        wfDebug( "$parameterMatch failed parameter validation\n" );
 -                                                                      $label = '|' . $parameterMatch;
 +                                                                      $label = $parameterMatch;
                                                                }
                                                }
  
                                        } else {
                                                // Last pipe wins.
 -                                              $label = '|' . $parameterMatch;
 +                                              $label = $parameterMatch;
                                        }
                                }
 -                              // Remove the pipe.
 -                              $label = substr( $label, 1 );
                        }
  
                        $ig->add( $title, $label, $alt, $link, $handlerOptions );
                                }
                        }
                        $this->mImageParams[$handlerClass] = $paramMap;
 -                      $this->mImageParamsMagicArray[$handlerClass] = new MagicWordArray( array_keys( $paramMap ) );
 +                      $this->mImageParamsMagicArray[$handlerClass] =
 +                              $this->magicWordFactory->newArray( array_keys( $paramMap ) );
                }
                return [ $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] ];
        }
                #  * bottom
                #  * text-bottom
  
 +              global $wgMediaInTargetLanguage;
 +
                # Protect LanguageConverter markup when splitting into parts
                $parts = StringUtils::delimiterExplode(
                        '-{', '}-', '|', $options, true /* allow nesting */
                                                                $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;
 +                                                              list( $paramName, $value ) =
 +                                                                      $this->parseLinkParameter(
 +                                                                              $this->stripAltText( $value, $holders )
 +                                                                      );
 +                                                              if ( $paramName ) {
                                                                        $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 ( $paramName === 'no-link' ) {
 +                                                                              $value = true;
 +                                                                      }
 +                                                                      if ( $paramName === 'link-url' ) {
                                                                                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;
                        # Use the "caption" for the tooltip text
                        $params['frame']['title'] = $this->stripAltText( $caption, $holders );
                }
 +              if ( $wgMediaInTargetLanguage ) {
 +                      $params['handler']['targetlang'] = $this->getTargetLanguage()->getCode();
 +              }
  
                Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] );
  
                # Linker does the rest
 -              $time = isset( $options['time'] ) ? $options['time'] : false;
 +              $time = $options['time'] ?? false;
                $ret = Linker::makeImageLink( $this, $title, $file, $params['frame'], $params['handler'],
                        $time, $descQuery, $this->mOptions->getThumbSize() );
  
                return $ret;
        }
  
 +      /**
 +       * Parse the value of 'link' parameter in image syntax (`[[File:Foo.jpg|link=<value>]]`).
 +       *
 +       * Adds an entry to appropriate link tables.
 +       *
 +       * @since 1.32
 +       * @return array of `[ type, target ]`, where:
 +       *   - `type` is one of:
 +       *     - `null`: Given value is not a valid link target, use default
 +       *     - `'no-link'`: Given value is empty, do not generate a link
 +       *     - `'link-url'`: Given value is a valid external link
 +       *     - `'link-title'`: Given value is a valid internal link
 +       *   - `target` is:
 +       *     - When `type` is `null` or `'no-link'`: `false`
 +       *     - When `type` is `'link-url'`: URL string corresponding to given value
 +       *     - When `type` is `'link-title'`: Title object corresponding to given value
 +       */
 +      public function parseLinkParameter( $value ) {
 +              $chars = self::EXT_LINK_URL_CLASS;
 +              $addr = self::EXT_LINK_ADDR;
 +              $prots = $this->mUrlProtocols;
 +              $type = null;
 +              $target = false;
 +              if ( $value === '' ) {
 +                      $type = 'no-link';
 +              } elseif ( preg_match( "/^((?i)$prots)/", $value ) ) {
 +                      if ( preg_match( "/^((?i)$prots)$addr$chars*$/u", $value, $m ) ) {
 +                              $this->mOutput->addExternalLink( $value );
 +                              $type = 'link-url';
 +                              $target = $value;
 +                      }
 +              } else {
 +                      $linkTitle = Title::newFromText( $value );
 +                      if ( $linkTitle ) {
 +                              $this->mOutput->addLink( $linkTitle );
 +                              $type = 'link-title';
 +                              $target = $linkTitle;
 +                      }
 +              }
 +              return [ $type, $target ];
 +      }
 +
        /**
         * @param string $caption
         * @param LinkHolderArray|bool $holders
                # that are later expanded to html- so expand them now and
                # remove the tags
                $tooltip = $this->mStripState->unstripBoth( $tooltip );
 +              # Compatibility hack!  In HTML certain entity references not terminated
 +              # by a semicolon are decoded (but not if we're in an attribute; that's
 +              # how link URLs get away without properly escaping & in queries).
 +              # But wikitext has always required semicolon-termination of entities,
 +              # so encode & where needed to avoid decode of semicolon-less entities.
 +              # See T209236 and
 +              # https://www.w3.org/TR/html5/syntax.html#named-character-references
 +              # T210437 discusses moving this workaround to Sanitizer::stripAllTags.
 +              $tooltip = preg_replace( "/
 +                      &                       # 1. entity prefix
 +                      (?=                     # 2. followed by:
 +                      (?:                     #  a. one of the legacy semicolon-less named entities
 +                              A(?:Elig|MP|acute|circ|grave|ring|tilde|uml)|
 +                              C(?:OPY|cedil)|E(?:TH|acute|circ|grave|uml)|
 +                              GT|I(?:acute|circ|grave|uml)|LT|Ntilde|
 +                              O(?:acute|circ|grave|slash|tilde|uml)|QUOT|REG|THORN|
 +                              U(?:acute|circ|grave|uml)|Yacute|
 +                              a(?:acute|c(?:irc|ute)|elig|grave|mp|ring|tilde|uml)|brvbar|
 +                              c(?:cedil|edil|urren)|cent(?!erdot;)|copy(?!sr;)|deg|
 +                              divide(?!ontimes;)|e(?:acute|circ|grave|th|uml)|
 +                              frac(?:1(?:2|4)|34)|
 +                              gt(?!c(?:c|ir)|dot|lPar|quest|r(?:a(?:pprox|rr)|dot|eq(?:less|qless)|less|sim);)|
 +                              i(?:acute|circ|excl|grave|quest|uml)|laquo|
 +                              lt(?!c(?:c|ir)|dot|hree|imes|larr|quest|r(?:Par|i(?:e|f|));)|
 +                              m(?:acr|i(?:cro|ddot))|n(?:bsp|tilde)|
 +                              not(?!in(?:E|dot|v(?:a|b|c)|)|ni(?:v(?:a|b|c)|);)|
 +                              o(?:acute|circ|grave|rd(?:f|m)|slash|tilde|uml)|
 +                              p(?:lusmn|ound)|para(?!llel;)|quot|r(?:aquo|eg)|
 +                              s(?:ect|hy|up(?:1|2|3)|zlig)|thorn|times(?!b(?:ar|)|d;)|
 +                              u(?:acute|circ|grave|ml|uml)|y(?:acute|en|uml)
 +                      )
 +                      (?:[^;]|$))     #  b. and not followed by a semicolon
 +                      # S = study, for efficiency
 +                      /Sx", '&amp;', $tooltip );
                $tooltip = Sanitizer::stripAllTags( $tooltip );
  
                return $tooltip;
         * @return array
         */
        public function getTags() {
 +              $this->firstCallInit();
                return array_merge(
                        array_keys( $this->mTransparentTagHooks ),
                        array_keys( $this->mTagHooks ),
                );
        }
  
 +      /**
 +       * @since 1.32
 +       * @return array
 +       */
 +      public function getFunctionSynonyms() {
 +              $this->firstCallInit();
 +              return $this->mFunctionSynonyms;
 +      }
 +
 +      /**
 +       * @since 1.32
 +       * @return string
 +       */
 +      public function getUrlProtocols() {
 +              return $this->mUrlProtocols;
 +      }
 +
        /**
         * Replace transparent tags in $text with the values given by the callbacks.
         *
                if ( !is_null( $this->mRevisionObject ) ) {
                        return $this->mRevisionObject;
                }
 -              if ( is_null( $this->mRevisionId ) ) {
 -                      return null;
 -              }
  
 +              // NOTE: try to get the RevisionObject even if mRevisionId is null.
 +              // This is useful when parsing revision that has not yet been saved.
 +              // However, if we get back a saved revision even though we are in
 +              // preview mode, we'll have to ignore it, see below.
 +              // NOTE: This callback may be used to inject an OLD revision that was
 +              // already loaded, so "current" is a bit of a misnomer. We can't just
 +              // skip it if mRevisionId is set.
                $rev = call_user_func(
                        $this->mOptions->getCurrentRevisionCallback(), $this->getTitle(), $this
                );
  
 -              # If the parse is for a new revision, then the callback should have
 -              # already been set to force the object and should match mRevisionId.
 -              # If not, try to fetch by mRevisionId for sanity.
 -              if ( $rev && $rev->getId() != $this->mRevisionId ) {
 +              if ( $this->mRevisionId === null && $rev && $rev->getId() ) {
 +                      // We are in preview mode (mRevisionId is null), and the current revision callback
 +                      // returned an existing revision. Ignore it and return null, it's probably the page's
 +                      // current revision, which is not what we want here. Note that we do want to call the
 +                      // callback to allow the unsaved revision to be injected here, e.g. for
 +                      // self-transclusion previews.
 +                      return null;
 +              }
 +
 +              // If the parse is for a new revision, then the callback should have
 +              // already been set to force the object and should match mRevisionId.
 +              // If not, try to fetch by mRevisionId for sanity.
 +              if ( $this->mRevisionId && $rev && $rev->getId() != $this->mRevisionId ) {
                        $rev = Revision::newFromId( $this->mRevisionId );
                }
  
         */
        public function getRevisionTimestamp() {
                if ( is_null( $this->mRevisionTimestamp ) ) {
 -                      global $wgContLang;
 -
                        $revObject = $this->getRevisionObject();
                        $timestamp = $revObject ? $revObject->getTimestamp() : wfTimestampNow();
  
                        # Since this value will be saved into the parser cache, served
                        # to other users, and potentially even used inside links and such,
                        # it needs to be consistent for all visitors.
 -                      $this->mRevisionTimestamp = $wgContLang->userAdjust( $timestamp, '' );
 -
 +                      $this->mRevisionTimestamp = $this->contLang->userAdjust( $timestamp, '' );
                }
                return $this->mRevisionTimestamp;
        }
                return '#' . Sanitizer::escapeIdForLink( $sectionName );
        }
  
 -      private static function makeLegacyAnchor( $sectionName ) {
 -              global $wgFragmentMode;
 -              if ( isset( $wgFragmentMode[1] ) && $wgFragmentMode[1] === 'legacy' ) {
 +      private function makeLegacyAnchor( $sectionName ) {
 +              $fragmentMode = $this->siteConfig->get( 'FragmentMode' );
 +              if ( isset( $fragmentMode[1] ) && $fragmentMode[1] === 'legacy' ) {
                        // ForAttribute() and ForLink() are the same for legacy encoding
                        $id = Sanitizer::escapeIdForAttribute( $sectionName, Sanitizer::ID_FALLBACK );
                } else {
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $sectionName = self::getSectionNameFromStrippedText( $text );
 -              return self::makeLegacyAnchor( $sectionName );
 +              return $this->makeLegacyAnchor( $sectionName );
        }
  
        /**
         * @return Parser A parser object that is not parsing anything
         */
        public function getFreshParser() {
 -              global $wgParserConf;
                if ( $this->mInParse ) {
 -                      return new $wgParserConf['class']( $wgParserConf );
 +                      return $this->factory->create();
                } else {
                        return $this;
                }
@@@ -37,7 -37,7 +37,7 @@@
  # You can also set the following parser properties via test options:
  #  wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel,
  #  wgLinkHolderBatchSize, wgRawHtml, wgInterwikiMagic,
 -#  wgEnableMagicLinks
 +#  wgEnableMagicLinks, wgMediaInTargetLanguage
  #
  # For testing purposes, temporary articles can created:
  # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
@@@ -56,24 -56,12 +56,24 @@@ Fo
  FOO
  !!endarticle
  
 +!!article
 +Foo''s bar''s
 +!!text
 +Article titles can contain single quotes!
 +!!endarticle
 +
  !!article
  Template:Foo
  !!text
  FOO
  !!endarticle
  
 +!! article
 +Template:redirect to foo
 +!! text
 +#REDIRECT [[Template:Foo]]
 +!! endarticle
 +
  !! article
  Template:Blank
  !! text
@@@ -121,14 -109,6 +121,14 @@@ Template:ech
  {{{1}}}
  !! endarticle
  
 +!! article
 +Template:echo3
 +!! text
 +{{{1}}}
 +{{{1}}}
 +{{{1}}}
 +!! endarticle
 +
  // For Serbian; localize Template namespace
  !! article
  Шаблон:Echo
@@@ -148,12 -128,6 +148,12 @@@ Template:echo_with_di
  <div>{{{1}}}</div>
  !! endarticle
  
 +!! article
 +Template:echo with depth
 +!! text
 +{{echo|{{{1}}}}}
 +!! endarticle
 +
  !! article
  Template:blank_param
  !! text
@@@ -263,7 -237,7 +263,7 @@@ Weirdo titles
  !!article
  Template:Bullet
  !!text
 -* Bar
 +*Bar
  !!endarticle
  
  !!article
@@@ -333,31 -307,23 +333,31 @@@ This is a simple paragraph
  !! test
  Paragraphs with extra newline spacing
  !! wikitext
 -foo
 +a
  
 -bar
 +b (+2 nls)
  
  
 -baz
 +c (+3 nls)
 +
  
  
 +d (+4 nls)
  
 -booz
 +
 +
 +
 +e (+5 nls)
  !! html
 -<p>foo
 -</p><p>bar
 +<p>a
 +</p><p>b (+2 nls)
  </p><p><br />
 -baz
 +c (+3 nls)
 +</p><p><br />
 +</p><p>d (+4 nls)
  </p><p><br />
 -</p><p>booz
 +</p><p><br />
 +e (+5 nls)
  </p>
  !! end
  
@@@ -529,6 -495,7 +529,6 @@@ Extra newlines followed by headin
  a
  
  
 -
  =b=
  [[a]]
  
  !! end
  
  !! test
 -Extra newlines between heading and content are swallowed
 +Extra newlines between heading and content are swallowed (Parsoid does not)
  !! wikitext
  =b=
  
  
  
  [[a]]
 -!! html
 +!! html/php+tidy
  <h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
  <p><a href="/index.php?title=A&amp;action=edit&amp;redlink=1" class="new" title="A (page does not exist)">a</a>
  </p>
 +!! html/parsoid
 +<h1 id="b">b</h1>
 +<p>
 +<br></p>
 +
 +<p><a rel="mw:WikiLink" href="./A" title="A">a</a></p>
 +!! end
 +
 +!! test
 +Extra new lines before and after lists are preserved
 +!! wikitext
 +a
 +
 +
 +*b
 +
 +
 +c
 +!! html/php+tidy
 +<p>a
 +</p><p><br />
 +</p>
 +<ul><li>b</li></ul>
 +<p><br />
 +c
 +</p>
 +!! html/parsoid
 +<p>a</p>
 +<p>
 +<br></p>
 +<ul><li>b</li></ul>
 +<p>
 +<br>
 +c</p>
  !! end
  
 +# Parsoid regression test
 +!!test
 +Multiple newlines after tables are converted to p-br-p tags
 +!!options
 +parsoid=wt2html,wt2wt
 +!!wikitext
 +{|
 +|x
 +|}
 +
 +
 +
 +
 +=b=
 +!!html/php+tidy
 +<table>
 +<tbody><tr>
 +<td>x
 +</td></tr></tbody></table>
 +<p><br />
 +</p><p><br />
 +</p>
 +<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1>
 +!!html/parsoid
 +<table>
 +<tbody>
 +<tr>
 +<td>x</td>
 +</tr>
 +</tbody>
 +</table>
 +<p><br/></p>
 +<p><br/></p>
 +<h1 id="b">b</h1>
 +!!end
 +
  !! test
  Heading with line break in nowiki
  !! options
@@@ -637,8 -534,8 +637,8 @@@ parsoid=wt2htm
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
 -== A <nowiki>B
 -C</nowiki> ==
 +==A <nowiki>B
 +C</nowiki>==
  !! html/php
  <h2><span id="A_B.0AC"></span><span class="mw-headline" id="A_B
  C">A B
@@@ -646,8 -543,8 +646,8 @@@ C</span><span class="mw-editsection"><s
  
  !! html/parsoid
  <h2 id="A_B
 -C"><span id="A_B.0AC" typeof="mw:FallbackId"></span> A <span typeof="mw:Nowiki">B
 -C</span> </h2>
 +C"><span id="A_B.0AC" typeof="mw:FallbackId"></span>A <span typeof="mw:Nowiki">B
 +C</span></h2>
  !! end
  
  !! test
@@@ -663,48 -560,48 +663,48 @@@ http://fr.wikipedia.org/wiki/ð\9f\8d
  !! test
  Simple list
  !! wikitext
 -* Item 1
 -* Item 2
 +*Item 1
 +*Item 2
  !! html
 -<ul><li> Item 1</li>
 -<li> Item 2</li></ul>
 +<ul><li>Item 1</li>
 +<li>Item 2</li></ul>
  
  !! end
  
  !! test
  Italics and bold
  !! wikitext
 -* plain
 -* plain''italic''plain
 -* plain''italic''plain''italic''plain
 -* plain'''bold'''plain
 -* plain'''bold'''plain'''bold'''plain
 -* plain''italic''plain'''bold'''plain
 -* plain'''bold'''plain''italic''plain
 -* plain''italic'''bold-italic'''italic''plain
 -* plain'''bold''bold-italic''bold'''plain
 -* plain'''''bold-italic'''italic''plain
 -* plain'''''bold-italic''bold'''plain
 -* plain''italic'''bold-italic'''''plain
 -* plain'''bold''bold-italic'''''plain
 -* plain l'''italic''plain
 -* plain l''''bold''' plain
 -!! html
 -<ul><li> plain</li>
 -<li> plain<i>italic</i>plain</li>
 -<li> plain<i>italic</i>plain<i>italic</i>plain</li>
 -<li> plain<b>bold</b>plain</li>
 -<li> plain<b>bold</b>plain<b>bold</b>plain</li>
 -<li> plain<i>italic</i>plain<b>bold</b>plain</li>
 -<li> plain<b>bold</b>plain<i>italic</i>plain</li>
 -<li> plain<i>italic<b>bold-italic</b>italic</i>plain</li>
 -<li> plain<b>bold<i>bold-italic</i>bold</b>plain</li>
 -<li> plain<i><b>bold-italic</b>italic</i>plain</li>
 -<li> plain<b><i>bold-italic</i>bold</b>plain</li>
 -<li> plain<i>italic<b>bold-italic</b></i>plain</li>
 -<li> plain<b>bold<i>bold-italic</i></b>plain</li>
 -<li> plain l'<i>italic</i>plain</li>
 -<li> plain l'<b>bold</b> plain</li></ul>
 +*plain
 +*plain''italic''plain
 +*plain''italic''plain''italic''plain
 +*plain'''bold'''plain
 +*plain'''bold'''plain'''bold'''plain
 +*plain''italic''plain'''bold'''plain
 +*plain'''bold'''plain''italic''plain
 +*plain''italic'''bold-italic'''italic''plain
 +*plain'''bold''bold-italic''bold'''plain
 +*plain'''''bold-italic'''italic''plain
 +*plain'''''bold-italic''bold'''plain
 +*plain''italic'''bold-italic'''''plain
 +*plain'''bold''bold-italic'''''plain
 +*plain l'''italic''plain
 +*plain l''''bold''' plain
 +!! html
 +<ul><li>plain</li>
 +<li>plain<i>italic</i>plain</li>
 +<li>plain<i>italic</i>plain<i>italic</i>plain</li>
 +<li>plain<b>bold</b>plain</li>
 +<li>plain<b>bold</b>plain<b>bold</b>plain</li>
 +<li>plain<i>italic</i>plain<b>bold</b>plain</li>
 +<li>plain<b>bold</b>plain<i>italic</i>plain</li>
 +<li>plain<i>italic<b>bold-italic</b>italic</i>plain</li>
 +<li>plain<b>bold<i>bold-italic</i>bold</b>plain</li>
 +<li>plain<i><b>bold-italic</b>italic</i>plain</li>
 +<li>plain<b><i>bold-italic</i>bold</b>plain</li>
 +<li>plain<i>italic<b>bold-italic</b></i>plain</li>
 +<li>plain<b>bold<i>bold-italic</i></b>plain</li>
 +<li>plain l'<i>italic</i>plain</li>
 +<li>plain l'<b>bold</b> plain</li></ul>
  
  !! end
  
@@@ -1350,33 -1247,32 +1350,33 @@@ Text-level semantic html elements in wi
  !! test
  Ruby markup (W3C-style)
  !! wikitext
 -; Mono-ruby for individual base characters
 -: <ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>
 -; Group ruby
 -: <ruby>今日<rt>きょう</rt></ruby>
 -; Jukugo ruby
 -: <ruby>法<rb>華</rb><rb>経</rb><rt>ほ</rt><rt>け</rt><rt>きょう</rt></ruby>
 -; Inline ruby
 -: <ruby>東<rb>京</rb><rp>(</rp><rt>とう</rt><rt>きょう</rt><rp>)</rp></ruby>
 -; Double-sided ruby
 -: <ruby><rb>旧</rb><rb>金</rb><rb>山</rb><rt>jiù</rt><rt>jīn</rt><rt>shān</rt><rtc>San Francisco</rtc></ruby>
 +;Mono-ruby for individual base characters
 +:<ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby>
 +;Group ruby
 +:<ruby>今日<rt>きょう</rt></ruby>
 +;Jukugo ruby
 +:<ruby>法<rb>華</rb><rb>経</rb><rt>ほ</rt><rt>け</rt><rt>きょう</rt></ruby>
 +;Inline ruby
 +:<ruby>東<rb>京</rb><rp>(</rp><rt>とう</rt><rt>きょう</rt><rp>)</rp></ruby>
 +;Double-sided ruby
 +:<ruby><rb>旧</rb><rb>金</rb><rb>山</rb><rt>jiù</rt><rt>jīn</rt><rt>shān</rt><rtc>San Francisco</rtc></ruby>
 +
  <ruby>
  <rb>♥</rb><rtc><rt>Heart</rt></rtc><rtc lang="fr"><rt>Cœur</rt></rtc>
  <rb>☘</rb><rtc><rt>Shamrock</rt></rtc><rtc lang="fr"><rt>Trèfle</rt></rtc>
  <rb>✶</rb><rtc><rt>Star</rt></rtc><rtc lang="fr"><rt>Étoile</rt></rtc>
  </ruby>
  !! html
 -<dl><dt> Mono-ruby for individual base characters</dt>
 -<dd> <ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby></dd>
 -<dt> Group ruby</dt>
 -<dd> <ruby>今日<rt>きょう</rt></ruby></dd>
 -<dt> Jukugo ruby</dt>
 -<dd> <ruby>法<rb>華</rb><rb>経</rb><rt>ほ</rt><rt>け</rt><rt>きょう</rt></ruby></dd>
 -<dt> Inline ruby</dt>
 -<dd> <ruby>東<rb>京</rb><rp>(</rp><rt>とう</rt><rt>きょう</rt><rp>)</rp></ruby></dd>
 -<dt> Double-sided ruby</dt>
 -<dd> <ruby><rb>旧</rb><rb>金</rb><rb>山</rb><rt>jiù</rt><rt>jīn</rt><rt>shān</rt><rtc>San Francisco</rtc></ruby></dd></dl>
 +<dl><dt>Mono-ruby for individual base characters</dt>
 +<dd><ruby>日<rt>に</rt>本<rt>ほん</rt>語<rt>ご</rt></ruby></dd>
 +<dt>Group ruby</dt>
 +<dd><ruby>今日<rt>きょう</rt></ruby></dd>
 +<dt>Jukugo ruby</dt>
 +<dd><ruby>法<rb>華</rb><rb>経</rb><rt>ほ</rt><rt>け</rt><rt>きょう</rt></ruby></dd>
 +<dt>Inline ruby</dt>
 +<dd><ruby>東<rb>京</rb><rp>(</rp><rt>とう</rt><rt>きょう</rt><rp>)</rp></ruby></dd>
 +<dt>Double-sided ruby</dt>
 +<dd><ruby><rb>旧</rb><rb>金</rb><rb>山</rb><rt>jiù</rt><rt>jīn</rt><rt>shān</rt><rtc>San Francisco</rtc></ruby></dd></dl>
  <p><ruby>
  <rb>♥</rb><rtc><rt>Heart</rt></rtc><rtc lang="fr"><rt>Cœur</rt></rtc>
  <rb>☘</rb><rtc><rt>Shamrock</rt></rtc><rtc lang="fr"><rt>Trèfle</rt></rtc>
@@@ -1400,7 -1296,7 +1400,7 @@@ Non-word characters don't terminate ta
  <s.foo> doesn't terminate </s.foo>
  
  <sub-ID#1>
 -!! html
 +!! html/php
  <p>&lt;blockquote|&gt;a&lt;/blockquote&gt;
  </p><p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;
  </p><p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;
@@@ -1435,7 -1331,7 +1435,7 @@@ Non-word characters don't terminate ta
  !! end
  
  ###
 -### See tests/parser/parserTestsParserHook.php for the <tåg> extension)
 +### See tests/parser/ParserTestParserHook.php for the <tåg> extension)
  ### This checks that HTML5 tags (with non-word characters in the tag
  ### name) make it safely through the parser -- the Sanitizer will
  ### munge them later, as it should.
@@@ -1463,10 -1359,12 +1463,10 @@@ parsoid=wt2htm
  </b>
  
  <s.foo>s</s>
 -!! html/php+tidy
 +!! html+tidy
  <p class="mw-empty-elt">
  </p><p>&lt;s.foo&gt;s
  </p>
 -!! html/parsoid
 -<p>&lt;s.foo&gt;s</p>
  !! end
  
  ###
  </p>
  !! end
  
 +!! test
 +post-expand include size being exceeded
 +!! options
 +maxincludesize=20
 +!! wikitext
 +{{echo3|1234567890}}
 +!! html
 +<p><a href="/wiki/Template:Echo3" title="Template:Echo3">Template:Echo3</a><!-- WARNING: template omitted, post-expand include size too large -->
 +</p>
 +!! end
 +
 +!! test
 +max template depth being reached
 +!! options
 +maxtemplatedepth=1
 +!! wikitext
 +{{echo with depth|too deep!}}
 +!! html
 +<p><span class="error">Template recursion depth limit exceeded (1)</span>
 +</p>
 +!! end
 +
 +!! test
 +multiple templates that are redirects
 +!! wikitext
 +{{redirect to foo}}
 +{{redirect to foo}}
 +!! html
 +<p>FOO
 +FOO
 +</p>
 +!! end
 +
  !! test
  Multiple comments should still parse as SOL-transparent
  !! options
@@@ -2025,18 -1890,22 +2025,18 @@@ a <div>foo</div
  </p>
  !! end
  
 -# Remex wraps empty tag runs with p-tags.
 -# Parsoid strips them out during p-wrapping.
  !! test
  No p-wrappable content
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  <span><div>x</div></span>
  <span><s><div>x</div></s></span>
  <small><em></em></small><span><s><div>x</div></s></span>
 -!! html/php+tidy
 +!! html+tidy
  <span><div>x</div></span>
  <span><s><div>x</div></s></span>
  <p><small><em></em></small></p><span><s><div>x</div></s></span>
 -!! html/parsoid
 -<span><div>x</div></span>
 -<span><s><div>x</div></s></span>
 -<small><em></em></small><span><s><div>x</div></s></span>
  !! end
  
  # T177612: Parsoid-only test
@@@ -2122,6 -1991,12 +2122,6 @@@ x </p><div>foo</div><p> 
  </p>
  !! end
  
 -# The difference between Parsoid & Remex here
 -# is because of Parsoid's Tidy-emulation code
 -# for p-wrapping. We'll start work to remove this
 -# emulation code in Parsoid sooner than later.
 -# Remex wraps empty tag runs with p-tags.
 -# Parsoid strips them out in a separate pass.
  !! test
  Empty lines between lines with block tags
  !! wikitext
  <link rel="mw:PageProp/Category" href="./Category:Ho" />
  !! end
  
 +!! test
 +Paragraph wrapping following unclosed table
 +!! options
 +parsoid=wt2html,html2html
 +!! wikitext
 +{|
 +|-
 +
 +{|
 +| x
 +|}
 +
 +a
 +
 +b
 +
 +c
 +!! html/php+tidy
 +<table>
 +
 +
 +</table><table>
 +<tbody><tr>
 +<td>x
 +</td></tr></tbody></table>
 +<p>a
 +</p><p>b
 +</p><p>c
 +</p>
 +!! html/parsoid
 +<table data-parsoid='{"autoInsertedEnd":true}'>
 +<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr>
 +
 +</tbody></table><table>
 +<tbody><tr data-parsoid='{"autoInsertedStart":true}'><td>x</td></tr>
 +</tbody></table>
 +
 +<p>a</p>
 +
 +<p>b</p>
 +
 +<p>c</p>
 +!! end
 +
 +!! test
 +Paragraph wrapping suppressed in html p
 +!! options
 +parsoid=wt2html,html2html
 +!! wikitext
 +<p>
 +
 +
 +hi
 +
 +
 +
 +</p>
 +!! html/php+tidy
 +<p>
 +
 +
 +hi
 +
 +
 +
 +</p>
 +!! html/parsoid
 +<p data-parsoid='{"stx":"html"}'>
 +
 +
 +hi
 +
 +
 +
 +</p>
 +!! end
 +
 +!! test
 +Dangling table row doesn't prevent p-wrapping
 +!! options
 +parsoid=wt2html,html2html
 +!! wikitext
 +{|
 +| hi
 +|-
 +|} ho
 +!! html/parsoid
 +<table>
 +<tbody><tr><td>hi</td></tr>
 +<tr class="mw-empty-elt"></tr>
 +</tbody></table><p> ho</p>
 +!! end
 +
  ###
  ### Preformatted text
  ###
@@@ -2506,11 -2288,6 +2506,11 @@@ Foo <del>bar</del> <ins>baz</ins> quu
  </p>
  </blockquote>
  
 +!! html+tidy
 +<blockquote>
 +<p>Foo <del>bar</del> <ins>baz</ins> quux
 +</p>
 +</blockquote>
  !! end
  
  !! test
@@@ -2523,7 -2300,7 +2523,7 @@@ T17491: <ins>/<del> in blockquote (2
  </blockquote>
  
  !! html+tidy
 -<blockquote><p>Foo </p><del>bar</del> <ins>baz</ins><p> quux
 +<blockquote><p>Foo <del>bar</del> <ins>baz</ins> quux
  </p></blockquote>
  !! end
  
@@@ -2834,7 -2611,7 +2834,7 @@@ two">hi</pre
  <pre class="one two">hi</pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/pre" about="#mwt2" class="one two" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
 +<pre class="one two" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
  !! end
  
  !! test
@@@ -2848,11 -2625,6 +2848,11 @@@ Barack Obama <President> of the United 
  </p>
  !! end
  
 +## Remex doesn't account for fostered content.
 +## The difference between Parsoid and the PHP parser can be attributed to core
 +## commit 674e8388cba and 710618f89af in Parsoid's repo.  Parsoid doesn't
 +## tokenize unmatched extension tags that shadow html tags as strings to ease
 +## an escaping mechanism.  See the comment in `maybeExtensionTag`.
  !! test
  Handle broken pre-like tags (T66025)
  !! options
@@@ -2869,25 -2641,12 +2869,25 @@@ parsoid=wt2htm
  <pre>x</pre>
  &lt;pre <table></table>
  !! html/parsoid
 -<pre about="#mwt1" typeof="mw:Transclusion mw:Extension/pre" data-parsoid='{"a":{"&lt;pre":null},"sa":{"&lt;pre":""},"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 +<pre typeof="mw:Extension/pre mw:Transclusion" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 +
 +<pre data-parsoid='{"stx":"html","src":"&lt;pre &lt;/table>","tagWidths":[13,0],"a":{"&lt;":null,"table":null},"sa":{"&lt;":"","table":""},"fostered":true,"autoInsertedEnd":true}'></pre><table data-parsoid='{"stx":"html","autoInsertedEnd":true}'></table>
 +!! end
  
 +## Similar to the above, but shows the difference between extension and html tags
 +!! test
 +Less than in attribute position
 +!! wikitext
 +<pre <pre>123</pre>
  
 -<p>&lt;pre </p>
 +<div <div>123</div>
 +!! html/php+tidy
 +<pre>123</pre><p>
 +&lt;div </p><div>123</div>
 +!! html/parsoid
 +<pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"&lt;pre":""},"body":{"extsrc":"123"}}'>123</pre><p>
  
 -<table></table>
 +&lt;div </p><div>123</div>
  !! end
  
  !! test
@@@ -2903,6 -2662,33 +2903,6 @@@ parsoid=wt2htm
  <pre typeof="mw:Extension/pre" about="#mwt2" style="width:50%;" data-mw='{"name":"pre","attrs":{"style":"width:50%;"},"body":{"extsrc":"{{echo|foo}}"}}'>{{echo|foo}}</pre>
  !! end
  
 -# TODO / maybe: fix wt2wt for this
 -!! test
 -Parsoid: Don't paragraph-wrap fosterable content
 -!! options
 -parsoid=wt2html
 -!! wikitext
 -{|
 -<td></td>
 -<td></td>
 -
 -
 -
 -|}
 -!! html
 -<table>
 -
 -<tbody>
 -<tr>
 -<td></td>
 -
 -<td></td></tr>
 -
 -
 -
 -</tbody></table>
 -!! end
 -
  !! test
  Self-closed pre
  !! wikitext
  <pre></pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{},"body":null}'></pre>
 +<pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{}}'></pre>
  !! end
  
  !! test
 -Parsoid: Don't paragraph-wrap fosterable content even if table syntax is unbalanced
 -!! options
 -parsoid=wt2html
 +Newline before table-close generates empty table row: T208619
  !! wikitext
  {|
 -<td>
 -<td>
 -</td>
 -
 -
  
  |}
 -!! html
 +!! html/php+tidy
 +<table>
 +
 +<tbody><tr><td></td></tr></tbody></table>
 +!! html/parsoid
 +<table data-parsoid='{}'>
 +
 +</table>
 +!! end
 +
 +# PHP has one more row in the output than Parsoid does: T208619
 +!! test
 +Parsoid: Don't paragraph-wrap fosterable content even if table syntax is unbalanced
 +!! options
 +parsoid=wt2html
 +!! wikitext
 +{|
 +<td>
 +<td>
 +</td>
 +
 +
 +
 +|}
 +!! html/php+tidy
 +<table>
 +<tbody><tr><td>
 +</td><td>
 +</td>
 +
 +
 +
 +</tr><tr><td></td></tr></tbody></table>
 +!! html/parsoid
  <table>
  
  <tbody>
@@@ -2991,7 -2751,7 +2991,7 @@@ Templates: Strip leading and trailing w
  </p><p>b
  </p><p>c
  </p>
 -<ul><li> d</li></ul>
 +<ul><li>d</li></ul>
  
  !! end
  
@@@ -3012,7 -2772,7 +3012,7 @@@ Templates: Don't strip whitespace from 
   e}}
  
  {{echo|
 -* f}}
 +*f}}
  
  {{echo|
   }}g
  </pre>
  <p><br />
  </p>
 -<ul><li> f</li></ul>
 +<ul><li>f</li></ul>
  <p><br />
  </p>
  <pre>g
@@@ -3231,13 -2991,12 +3231,13 @@@ data-mw='{"parts":[{"template":{"target
  
  !! test
  Parsoid: Pipe in template with nested template in external link target in template parameter (seriously)
 -!! options
 -parsoid
  !! wikitext
  {{echo|[{{fullurl:{{FULLPAGENAME}}|action=edit}} bar]}}
 -!! html
 -<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[{{fullurl:{{FULLPAGENAME}}|action=edit}} bar]"}},"i":0}}]}'>[Main Page bar]</p>
 +!! html/php+tidy
 +<p><a rel="nofollow" class="external text" href="http://example.org/index.php?title=Parser_test&amp;action=edit">bar</a>
 +</p>
 +!! html/parsoid
 +<p><a rel="mw:ExtLink" class="external text" href="http://example.org/index.php?title=Parser_test&amp;action=edit" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[{{fullurl:{{FULLPAGENAME}}|action=edit}} bar]"}},"i":0}}]}'>bar</a></p>
  !! end
  
  !! test
  2c. Indent-Pre and tables (T44252)
  !! wikitext
  {|
 - |+ foo
 - !  | bar
 + |+foo
 + !  |bar
  |}
  !! html
  <table>
 -<caption> foo
 +<caption>foo
  </caption>
  <tr>
 -<th> bar
 +<th>bar
  </th></tr></table>
  
  !!end
  !! wikitext
   a
   {|
 - | b
 + |b
   |}
  !! html/php
  <pre>a
  </pre>
  <table>
  <tr>
 -<td> b
 +<td>b
  </td></tr></table>
  
  !! html/parsoid
  
  !! end
  
 -!!test
 +!! test
 +2h. Indent pre in tables
 +!! options
 +parsoid=wt2html,html2html
 +!! wikitext
 +{|
 + !
 + foo
 + !
 + bar
 + |-
 + |
 + baz
 + {{!}}
 + bam
 + |}
 +!! html/php
 +<table>
 +<tr>
 +<th>
 +<pre>foo
 +</pre>
 +</th>
 +<th>
 +<pre>bar
 +</pre>
 +</th></tr>
 +<tr>
 +<td>
 +<pre>baz
 +</pre>
 +</td>
 +<td>
 +<pre>bam
 +</pre>
 +</td></tr></table>
 +
 +!! html/parsoid
 +<table>
 + <tbody><tr><th>
 +<pre>foo</pre>
 +</th><th>
 +<pre>bar</pre>
 +</th></tr><tr>
 + <td>
 +<pre>baz</pre>
 +</td><td data-parsoid='{"startTagSrc":"{{!}}"}'>
 +<pre>bam</pre>
 +</td></tr></tbody></table>
 +!! end
 +
 +!! test
  3a. Indent-Pre and block tags (single-line html)
  !! wikitext
   a <p> foo </p>
   c <blockquote> foo </blockquote>
  <pre><span> foo </span>
  </pre>
 -!! html/parsoid
 - <p>a </p><p data-parsoid='{"stx":"html"}'> foo </p>
 - <p>b </p><div data-parsoid='{"stx":"html"}'> foo </div>
 - <p>c </p><blockquote data-parsoid='{"stx":"html"}'> foo </blockquote>
 -<pre><span> foo </span>
 -</pre>
  !! html/php+tidy
  <p> a </p><p> foo </p><p>
   b </p><div> foo </div><p>
   c </p><blockquote><p> foo </p></blockquote>
  <pre><span> foo </span>
  </pre>
 +!! html/parsoid
 +<p> a </p><p data-parsoid='{"stx":"html"}'> foo </p><p>
 + b </p><div data-parsoid='{"stx":"html"}'> foo </div><p>
 + c </p><blockquote data-parsoid='{"stx":"html"}'><p> foo </p></blockquote>
 +<pre><span data-parsoid='{"stx":"html"}'> foo </span></pre>
  !! end
  
 -!!test
 +!! test
  3b. Indent-Pre and block tags (multi-line html)
  !! wikitext
   a <span>foo</span>
 - b <div> foo </div>
 -!! html
 +<!-- comment --> b <div> foo </div>
 +!! html/php
  <pre>a <span>foo</span>
  </pre>
   b <div> foo </div>
  
  !! html/parsoid
  <pre>a <span data-parsoid='{"stx":"html"}'>foo</span></pre>
 - b <div data-parsoid='{"stx":"html"}'> foo </div>
 +<!-- comment --> <p>b </p><div data-parsoid='{"stx":"html"}'> foo </div>
  !! html/php+tidy
  <pre>a <span>foo</span>
  </pre><p>
   b </p><div> foo </div>
 -!!end
 +!! end
  
  !!test
  3c. Indent-Pre and block tags (pre-content on separate line)
  
  !! test
  4. Indent-Pre and extension tags
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
   a <tag />
 -!! html/php
 - a <pre>
 -NULL
 +!! html/php+tidy
 +<p> a </p><pre>NULL
  array (
  )
  </pre>
 -
  !! html/parsoid
 - a <pre typeof="mw:Extension/tag" about="#mwt2" data-parsoid='{}' data-mw='{"name":"tag","attrs":{},"body":null}'></pre>
 +<p> a </p><pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{}}'></pre>
  !! end
  
  !! test
   <pre class="123">hi</pre>
  
  !! html/parsoid
 - <pre typeof="mw:Extension/pre" about="#mwt2" class="123" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
 + <pre class="123" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
  !! end
  
  !!test
@@@ -3990,19 -3699,19 +3990,19 @@@ HTML-pre: 3: other wikitex
  !! test
  Simple definition
  !! wikitext
 -; name : Definition
 +;name :Definition
  !! html
 -<dl><dt> name&#160;</dt>
 -<dd> Definition</dd></dl>
 +<dl><dt>name</dt>
 +<dd>Definition</dd></dl>
  
  !! end
  
  !! test
  Definition list for indentation only
  !! wikitext
 -: Indented text
 +:Indented text
  !! html
 -<dl><dd> Indented text</dd></dl>
 +<dl><dd>Indented text</dd></dl>
  
  !! end
  
@@@ -4019,10 -3728,10 +4019,10 @@@ Definition list with no spac
  !! test
  Definition list with URL link
  !! wikitext
 -; http://example.com/ : definition
 +;http://example.com/ :definition
  !! html
 -<dl><dt> <a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a>&#160;</dt>
 -<dd> definition</dd></dl>
 +<dl><dt><a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a></dt>
 +<dd>definition</dd></dl>
  
  !! end
  
@@@ -4039,10 -3748,10 +4039,10 @@@ Definition list with bracketed URL lin
  !! test
  Definition list with wikilink containing colon
  !! wikitext
 -; [[Help:FAQ]]: The least-read page on Wikipedia
 +;[[Help:FAQ]]:The least-read page on Wikipedia
  !! html
 -<dl><dt> <a href="/index.php?title=Help:FAQ&amp;action=edit&amp;redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt>
 -<dd> The least-read page on Wikipedia</dd></dl>
 +<dl><dt><a href="/index.php?title=Help:FAQ&amp;action=edit&amp;redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt>
 +<dd>The least-read page on Wikipedia</dd></dl>
  
  !! end
  
  !! test
  Definition list with news link containing colon
  !! wikitext
 -;  news:alt.wikipedia.rox: This isn't even a real newsgroup!
 +;news:alt.wikipedia.rox :This isn't even a real newsgroup!
  !! html/php
 -<dl><dt>  <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt>
 -<dd> This isn't even a real newsgroup!</dd></dl>
 +<dl><dt><a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt>
 +<dd>This isn't even a real newsgroup!</dd></dl>
  
  !! html/parsoid
 -<dl><dt>  <a rel="mw:ExtLink" class="external free" href="news:alt.wikipedia.rox" data-parsoid='{"stx":"url"}'>news:alt.wikipedia.rox</a></dt><dd data-parsoid='{"stx":"row"}'> This isn't even a real newsgroup!</dd></dl>
 +<dl><dt><a rel="mw:ExtLink" class="external free" href="news:alt.wikipedia.rox" data-parsoid='{"stx":"url"}'>news:alt.wikipedia.rox</a></dt><dd data-parsoid='{"stx":"row"}'>This isn't even a real newsgroup!</dd></dl>
  !! end
  
  !! test
  Malformed definition list with colon
  !! wikitext
 -;  news:alt.wikipedia.rox -- don't crash or enter an infinite loop
 +;news:alt.wikipedia.rox -- don't crash or enter an infinite loop
  !! html
 -<dl><dt>  <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop</dt></dl>
 +<dl><dt><a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop</dt></dl>
  
  !! end
  
  !! test
  Definition lists: colon in external link text
  !! wikitext
 -; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up
 +;[http://www.wikipedia2.org/ Wikipedia :The Next Generation] :OK, I made that up
  !! html
 -<dl><dt> <a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia&#160;: The Next Generation</a></dt>
 -<dd> OK, I made that up</dd></dl>
 +<dl><dt><a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia :The Next Generation</a></dt>
 +<dd>OK, I made that up</dd></dl>
  
  !! end
  
@@@ -4090,30 -3799,30 +4090,30 @@@ Definition lists: colon in HTML attribu
  !! test
  Definition lists: self-closed tag
  !! wikitext
 -;one<br/>two : two-line fun
 +;one<br/>two :two-line fun
  !! html
 -<dl><dt>one<br />two&#160;</dt>
 -<dd> two-line fun</dd></dl>
 +<dl><dt>one<br />two</dt>
 +<dd>two-line fun</dd></dl>
  
  !! end
  
  !! test
  Definition lists: ignore colons inside tags
  !! wikitext
 -;one <b>two : tag <i>fun:</i>:</b>: def
 +;one <b>two : tag <i>fun:</i>:</b>:def
  !! html
  <dl><dt>one <b>two&#160;: tag <i>fun:</i>:</b></dt>
 -<dd> def</dd></dl>
 +<dd>def</dd></dl>
  
  !! end
  
  !! test
  Definition lists: excess closed tags
  !! wikitext
 -;one</b>two : bad tag fun
 +;one</b>two :bad tag fun
  !! html/php+tidy
 -<dl><dt>onetwo&#160;</dt>
 -<dd> bad tag fun</dd></dl>
 +<dl><dt>onetwo</dt>
 +<dd>bad tag fun</dd></dl>
  !! html/parsoid
  <dl>
  <dt>onetwo</dt>
@@@ -4144,14 -3853,14 +4144,14 @@@ T13748: Literal closing tag
  Definition and unordered list using wiki syntax nested in unordered list using html tags.
  !! wikitext
  <ul><li>
 -; term : description
 -* unordered
 +;term :description
 +*unordered
  </li></ul>
  !! html
  <ul><li>
 -<dl><dt> term&#160;</dt>
 -<dd> description</dd></dl>
 -<ul><li> unordered</li></ul>
 +<dl><dt>term</dt>
 +<dd>description</dd></dl>
 +<ul><li>unordered</li></ul>
  </li></ul>
  
  !! end
  !! test
  Definition list with empty definition and following paragraph
  !! wikitext
 -; term:
 +;term:
 +
  Paragraph text
  !! html
 -<dl><dt> term</dt>
 +<dl><dt>term</dt>
  <dd></dd></dl>
  <p>Paragraph text
  </p>
@@@ -4249,29 -3957,6 +4249,29 @@@ should be left alon
  </p>
  !! end
  
 +!! test
 +Definition Lists: Hacky use to indent tables (with content following table)
 +!! wikitext
 +:{|
 +|foo
 +|bar
 +|} <!--c1--> this text should be part of the dl
 +!! html/php+tidy
 +<dl><dd><table>
 +<tbody><tr>
 +<td>foo
 +</td>
 +<td>bar
 +</td></tr></tbody></table>  this text should be part of the dl</dd></dl>
 +!! html/parsoid
 +<dl><dd><table>
 +<tbody><tr>
 +<td>foo
 +</td>
 +<td>bar
 +</td></tr></tbody></table> <!--c1--> this text should be part of the dl</dd></dl>
 +!! end
 +
  !! test
  Definition Lists: Hacky use to indent tables, with comments (T65979)
  !! wikitext
@@@ -4294,8 -3979,6 +4294,8 @@@ should be left alone</p
  
  !! test
  Definition Lists: Hacky use to indent tables, with comment before table
 +!!options
 +parsoid=wt2html
  !! wikitext
  ::<!-- foo -->{|
  |foo
  !! test
  Definition Lists: Hacky use to indent tables (WS-insensitive)
  !! wikitext
 -: {|
 +:{|
  |a
  |} 
  !! html/php
  </td></tr></table></dd></dl>
  
  !! html/parsoid
 -<dl><dd> <table>
 +<dl><dd><table>
  <tbody><tr><td>a</td></tr>
 -</tbody></table> </dd></dl>
 +</tbody></table></dd></dl>
  !! end
  
  ## The PHP parser treats : items (dd) without a corresponding ; item (dt)
@@@ -4366,24 -4049,22 +4366,24 @@@ Table / list interaction: indented tabl
  !! wikitext
  :{|
  |-
 -| a
 -* b
 +|a
 +
 +*b
  |-
 -| c
 -* d
 +|c
 +
 +*d
  |}
  !! html
  <dl><dd><table>
  
  <tr>
 -<td> a
 -<ul><li> b</li></ul>
 +<td>a
 +<ul><li>b</li></ul>
  </td></tr>
  <tr>
 -<td> c
 -<ul><li> d</li></ul>
 +<td>c
 +<ul><li>d</li></ul>
  </td></tr></table></dd></dl>
  
  !! end
@@@ -4491,30 -4172,30 +4491,30 @@@ Definition Lists: Nesting: Test 
  !! test
  Definition Lists: Mixed Lists: Test 1
  !! wikitext
 -:;* foo
 -::* bar
 -:; baz
 +:;*foo
 +::*bar
 +:;baz
  !! html/php
 -<dl><dd><dl><dt><ul><li> foo</li>
 -<li> bar</li></ul></dt></dl>
 -<dl><dt> baz</dt></dl></dd></dl>
 +<dl><dd><dl><dt><ul><li>foo</li>
 +<li>bar</li></ul></dt></dl>
 +<dl><dt>baz</dt></dl></dd></dl>
  
  !! html/php+tidy
 -<dl><dd><dl><dt><ul><li> foo</li>
 -<li> bar</li></ul></dt></dl>
 -<dl><dt> baz</dt></dl></dd></dl>
 +<dl><dd><dl><dt><ul><li>foo</li>
 +<li>bar</li></ul></dt></dl>
 +<dl><dt>baz</dt></dl></dd></dl>
  !! html/parsoid
  <dl>
  <dd><dl>
  <dt><ul>
 -<li> foo
 +<li>foo
  </li>
  </ul></dt>
  <dd><ul>
 -<li> bar
 +<li>bar
  </li>
  </ul></dd>
 -<dt> baz</dt>
 +<dt>baz</dt>
  </dl></dd>
  </dl>
  !! end
  !! test
  Definition Lists: Mixed Lists: Test 2
  !! wikitext
 -*: d1
 -*: d2
 +*:d1
 +*:d2
  !! html
 -<ul><li><dl><dd> d1</dd>
 -<dd> d2</dd></dl></li></ul>
 +<ul><li><dl><dd>d1</dd>
 +<dd>d2</dd></dl></li></ul>
  
  !! end
  
  !! test
  Definition Lists: Mixed Lists: Test 3
  !! wikitext
 -*::: d1
 -*::: d2
 +*:::d1
 +*:::d2
  !! html
 -<ul><li><dl><dd><dl><dd><dl><dd> d1</dd>
 -<dd> d2</dd></dl></dd></dl></dd></dl></li></ul>
 +<ul><li><dl><dd><dl><dd><dl><dd>d1</dd>
 +<dd>d2</dd></dl></dd></dl></dd></dl></li></ul>
  
  !! end
  
@@@ -4549,9 -4230,9 +4549,9 @@@ Definition Lists: Mixed Lists: Test 
  *;d1 :d2
  *;d3 :d4
  !! html
 -<ul><li><dl><dt>d1&#160;</dt>
 +<ul><li><dl><dt>d1</dt>
  <dd>d2</dd>
 -<dt>d3&#160;</dt>
 +<dt>d3</dt>
  <dd>d4</dd></dl></li></ul>
  
  !! end
  Definition Lists: Mixed Lists: Test 5
  !! wikitext
  *:d1
 -*:: d2
 +*::d2
  !! html
  <ul><li><dl><dd>d1
 -<dl><dd> d2</dd></dl></dd></dl></li></ul>
 +<dl><dd>d2</dd></dl></dd></dl></li></ul>
  
  !! end
  
  Definition Lists: Mixed Lists: Test 6
  !! wikitext
  #*:d1
 -#*::: d3
 +#*:::d3
  !! html
  <ol><li><ul><li><dl><dd>d1
 -<dl><dd><dl><dd> d3</dd></dl></dd></dl></dd></dl></li></ul></li></ol>
 +<dl><dd><dl><dd>d3</dd></dl></dd></dl></dd></dl></li></ul></li></ol>
  
  !! end
  
  !! test
  Definition Lists: Mixed Lists: Test 7
  !! wikitext
 -:* d1
 -:* d2
 +:*d1
 +:*d2
  !! html
 -<dl><dd><ul><li> d1</li>
 -<li> d2</li></ul></dd></dl>
 +<dl><dd><ul><li>d1</li>
 +<li>d2</li></ul></dd></dl>
  
  !! end
  
  !! test
  Definition Lists: Mixed Lists: Test 8
  !! wikitext
 -:* d1
 -::* d2
 +:*d1
 +::*d2
  !! html
 -<dl><dd><ul><li> d1</li></ul>
 -<dl><dd><ul><li> d2</li></ul></dd></dl></dd></dl>
 +<dl><dd><ul><li>d1</li></ul>
 +<dl><dd><ul><li>d2</li></ul></dd></dl></dd></dl>
  
  !! end
  
@@@ -4610,7 -4291,7 +4610,7 @@@ Definition Lists: Mixed Lists: Test 
  !! wikitext
  *;foo :bar
  !! html
 -<ul><li><dl><dt>foo&#160;</dt>
 +<ul><li><dl><dt>foo</dt>
  <dd>bar</dd></dl></li></ul>
  
  !! end
@@@ -4621,7 -4302,7 +4621,7 @@@ Definition Lists: Mixed Lists: Test 1
  !! wikitext
  *#;foo :bar
  !! html
 -<ul><li><ol><li><dl><dt>foo&#160;</dt>
 +<ul><li><ol><li><dl><dt>foo</dt>
  <dd>bar</dd></dl></li></ol></li></ul>
  
  !! end
@@@ -4654,15 -4335,15 +4654,15 @@@ Definition Lists: Mixed Lists: Test 1
  *#*#;*;;foo :bar
  *#*#;boo :baz
  !! html/php
 -<ul><li><ol><li><ul><li><ol><li><dl><dt>foo&#160;</dt>
 +<ul><li><ol><li><ul><li><ol><li><dl><dt>foo</dt>
  <dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dd></dl></li></ul></dd></dl>
 -<dl><dt>boo&#160;</dt>
 +<dl><dt>boo</dt>
  <dd>baz</dd></dl></li></ol></li></ul></li></ol></li></ul>
  
  !! html/php+tidy
 -<ul><li><ol><li><ul><li><ol><li><dl><dt>foo&#160;</dt>
 +<ul><li><ol><li><ul><li><ol><li><dl><dt>foo</dt>
  <dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dt></dl></li></ul></dd></dl></li></ol></li></ul>
 -<dl><dt>boo&#160;</dt>
 +<dl><dt>boo</dt>
  <dd>baz</dd></dl></li></ol></li></ul>
  !! html/parsoid
  <ul>
  <dl>
  <dt>
  <dl>
 -<dt>foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'>&nbsp;</span></dt>
 +<dt>foo</dt>
  <dd data-parsoid='{"stx":"row"}'>bar</dd>
  </dl></dt>
  </dl></li>
  </ul></dt>
 -<dt>boo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'>&nbsp;</span></dt>
 +<dt>boo</dt>
  <dd data-parsoid='{"stx":"row"}'>baz</dd>
  </dl></li>
  </ol></li>
  </ul>
  !! end
  
 +!! test
 +Definition Lists: Mixed Lists: Test 13
 +!! wikitext
 +*#*#;*;;foo : bar
 +*#*#;boo : baz
 +!! html+tidy
 +<ul><li><ol><li><ul><li><ol><li><dl><dt>foo&#160;</dt>
 +<dd><ul><li><dl><dt><dl><dt>bar</dt></dl></dt></dl></li></ul></dd></dl></li></ol></li></ul>
 +<dl><dt>boo&#160;</dt>
 +<dd>baz</dd></dl></li></ol></li></ul>
 +!! end
 +
  # FIXME: Maybe get rid of this test?
  # From whitelist:
  # * The test is wrong, there are two colons where there should be :;
  !! test
  Definition Lists: Weird Ones: Test 1
  !! wikitext
 -*#;*::;; foo : bar (who uses this?)
 +*#;*::;;foo :bar (who uses this?)
  !! html/php+tidy
 -<ul><li><ol><li><dl><dt> foo&#160;</dt>
 -<dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt> bar (who uses this?)</dt></dl></dt></dl></dd></dl></dd></dl></li></ul></dd></dl></li></ol></li></ul>
 +<ul><li><ol><li><dl><dt>foo</dt>
 +<dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt>bar (who uses this?)</dt></dl></dt></dl></dd></dl></dd></dl></li></ul></dd></dl></li></ol></li></ul>
  !! html/parsoid
  <ul>
  <li>
  <dl>
  <dt>
  <dl>
 -<dt> foo<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span></dt>
 -<dd data-parsoid='{"stx":"row"}'> bar (who uses this?)</dd>
 +<dt>foo</dt>
 +<dd data-parsoid='{"stx":"row"}'>bar (who uses this?)</dd>
  </dl></dt>
  </dl></dd>
  </dl></dd>
@@@ -4791,29 -4460,29 +4791,29 @@@ Definition Lists: colons occurring in t
  Definition Lists: colons and tables 1
  !! wikitext
  :{|
 -| x
 +|x
  |}
  :{|
 -| y
 +|y
  |}
  !! html/php
  <dl><dd><table>
  <tr>
 -<td> x
 +<td>x
  </td></tr></table></dd></dl>
  <dl><dd><table>
  <tr>
 -<td> y
 +<td>y
  </td></tr></table></dd></dl>
  
  !! html/parsoid
  <dl><dd><table>
  <tr>
 -<td> x
 +<td>x
  </td></tr></table></dd>
  <dd><table>
  <tr>
 -<td> y
 +<td>y
  </td></tr></table></dd></dl>
  !! end
  
@@@ -5268,10 -4937,10 +5268,10 @@@ parsoid=wt2htm
  !! wikitext
  URL in text: [http://example.com http://example.com]
  !! html/php
 -<p>URL in text: <a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>
 +<p>URL in text: <a rel="nofollow" class="external text" href="http://example.com">http://example.com</a>
  </p>
  !! html/parsoid
 -<p>URL in text: <a rel="mw:ExtLink" class="external free" href="http://example.com">http://example.com</a></p>
 +<p>URL in text: <a rel="mw:ExtLink" class="external text" href="http://example.com">http://example.com</a></p>
  !! end
  
  !! test
@@@ -5874,62 -5543,61 +5874,62 @@@ IPv6 urls, autolink format (T23261
  http://[2404:130:0:1000::187:2]/index.php
  
  Examples from RFC 2373, section 2.2:
 -* http://[1080::8:800:200C:417A]/unicast
 -* http://[FF01::101]/multicast
 -* http://[::1]/loopback
 -* http://[::]/unspecified
 -* http://[::13.1.68.3]/ipv4compat
 -* http://[::FFFF:129.144.52.38]/ipv4compat
 +
 +*http://[1080::8:800:200C:417A]/unicast
 +*http://[FF01::101]/multicast
 +*http://[::1]/loopback
 +*http://[::]/unspecified
 +*http://[::13.1.68.3]/ipv4compat
 +*http://[::FFFF:129.144.52.38]/ipv4compat
  
  Examples from RFC 2732, section 2:
 -* http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
 -* http://[1080:0:0:0:8:800:200C:417A]/index.html
 -* http://[3ffe:2a00:100:7031::1]
 -* http://[1080::8:800:200C:417A]/foo
 -* http://[::192.9.5.5]/ipng
 -* http://[::FFFF:129.144.52.38]:80/index.html
 -* http://[2010:836B:4179::836B:4179]
  
 +*http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
 +*http://[1080:0:0:0:8:800:200C:417A]/index.html
 +*http://[3ffe:2a00:100:7031::1]
 +*http://[1080::8:800:200C:417A]/foo
 +*http://[::192.9.5.5]/ipng
 +*http://[::FFFF:129.144.52.38]:80/index.html
 +*http://[2010:836B:4179::836B:4179]
  !! html/php
  <p><a rel="nofollow" class="external free" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a>
  </p><p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc2373">RFC 2373</a>, section 2.2:
  </p>
 -<ul><li> <a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
 +<ul><li><a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
  <p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc2732">RFC 2732</a>, section 2:
  </p>
 -<ul><li> <a rel="nofollow" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
 -<li> <a rel="nofollow" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
 +<ul><li><a rel="nofollow" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
 +<li><a rel="nofollow" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
  
  !! html/parsoid
  <p><a rel="mw:ExtLink" class="external free" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a></p>
  
 -<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external text">RFC 2373</a>, section 2.2:</p>
 -<ul><li> <a rel="mw:ExtLink" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
 +<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external mw-magiclink">RFC 2373</a>, section 2.2:</p>
 +<ul><li><a rel="mw:ExtLink" class="external free" href="http://[1080::8:800:200C:417A]/unicast">http://[1080::8:800:200C:417A]/unicast</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[FF01::101]/multicast">http://[FF01::101]/multicast</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::1]/loopback">http://[::1]/loopback</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::]/unspecified">http://[::]/unspecified</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::13.1.68.3]/ipv4compat">http://[::13.1.68.3]/ipv4compat</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::FFFF:129.144.52.38]/ipv4compat">http://[::FFFF:129.144.52.38]/ipv4compat</a></li></ul>
  
 -<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external text">RFC 2732</a>, section 2:</p>
 -<ul><li> <a rel="mw:ExtLink" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
 -<li> <a rel="mw:ExtLink" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
 +<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external mw-magiclink">RFC 2732</a>, section 2:</p>
 +<ul><li><a rel="mw:ExtLink" class="external free" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">http://[1080:0:0:0:8:800:200C:417A]/index.html</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[3ffe:2a00:100:7031::1]">http://[3ffe:2a00:100:7031::1]</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[1080::8:800:200C:417A]/foo">http://[1080::8:800:200C:417A]/foo</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::192.9.5.5]/ipng">http://[::192.9.5.5]/ipng</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[::FFFF:129.144.52.38]:80/index.html">http://[::FFFF:129.144.52.38]:80/index.html</a></li>
 +<li><a rel="mw:ExtLink" class="external free" href="http://[2010:836B:4179::836B:4179]">http://[2010:836B:4179::836B:4179]</a></li></ul>
  !! end
  
  !! test
@@@ -5938,62 -5606,61 +5938,62 @@@ IPv6 urls, bracketed format (T23261
  [http://[2404:130:0:1000::187:2]/index.php test]
  
  Examples from RFC 2373, section 2.2:
 -* [http://[1080::8:800:200C:417A] unicast]
 -* [http://[FF01::101] multicast]
 -* [http://[::1]/ loopback]
 -* [http://[::] unspecified]
 -* [http://[::13.1.68.3] ipv4compat]
 -* [http://[::FFFF:129.144.52.38] ipv4compat]
 +
 +*[http://[1080::8:800:200C:417A] unicast]
 +*[http://[FF01::101] multicast]
 +*[http://[::1]/ loopback]
 +*[http://[::] unspecified]
 +*[http://[::13.1.68.3] ipv4compat]
 +*[http://[::FFFF:129.144.52.38] ipv4compat]
  
  Examples from RFC 2732, section 2:
 -* [http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html 1]
 -* [http://[1080:0:0:0:8:800:200C:417A]/index.html 2]
 -* [http://[3ffe:2a00:100:7031::1] 3]
 -* [http://[1080::8:800:200C:417A]/foo 4]
 -* [http://[::192.9.5.5]/ipng 5]
 -* [http://[::FFFF:129.144.52.38]:80/index.html 6]
 -* [http://[2010:836B:4179::836B:4179] 7]
  
 +*[http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html 1]
 +*[http://[1080:0:0:0:8:800:200C:417A]/index.html 2]
 +*[http://[3ffe:2a00:100:7031::1] 3]
 +*[http://[1080::8:800:200C:417A]/foo 4]
 +*[http://[::192.9.5.5]/ipng 5]
 +*[http://[::FFFF:129.144.52.38]:80/index.html 6]
 +*[http://[2010:836B:4179::836B:4179] 7]
  !! html/php
  <p><a rel="nofollow" class="external text" href="http://[2404:130:0:1000::187:2]/index.php">test</a>
  </p><p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc2373">RFC 2373</a>, section 2.2:
  </p>
 -<ul><li> <a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[FF01::101]">multicast</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::1]/">loopback</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::]">unspecified</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
 +<ul><li><a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[FF01::101]">multicast</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::1]/">loopback</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::]">unspecified</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
  <p>Examples from <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc2732">RFC 2732</a>, section 2:
  </p>
 -<ul><li> <a rel="nofollow" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
 +<ul><li><a rel="nofollow" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
 +<li><a rel="nofollow" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
  
  !! html/parsoid
  <p><a rel="mw:ExtLink" class="external text" href="http://[2404:130:0:1000::187:2]/index.php">test</a></p>
  
 -<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external text">RFC 2373</a>, section 2.2:</p>
 -<ul><li> <a rel="mw:ExtLink" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[FF01::101]">multicast</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::1]/">loopback</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::]">unspecified</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
 +<p>Examples from <a href="https://tools.ietf.org/html/rfc2373" rel="mw:ExtLink" class="external mw-magiclink">RFC 2373</a>, section 2.2:</p>
 +<ul><li><a rel="mw:ExtLink" class="external text" href="http://[1080::8:800:200C:417A]">unicast</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[FF01::101]">multicast</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::1]/">loopback</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::]">unspecified</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::13.1.68.3]">ipv4compat</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::FFFF:129.144.52.38]">ipv4compat</a></li></ul>
  
 -<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external text">RFC 2732</a>, section 2:</p>
 -<ul><li> <a rel="mw:ExtLink" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
 -<li> <a rel="mw:ExtLink" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
 +<p>Examples from <a href="https://tools.ietf.org/html/rfc2732" rel="mw:ExtLink" class="external mw-magiclink">RFC 2732</a>, section 2:</p>
 +<ul><li><a rel="mw:ExtLink" class="external text" href="http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html">1</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[1080:0:0:0:8:800:200C:417A]/index.html">2</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[3ffe:2a00:100:7031::1]">3</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[1080::8:800:200C:417A]/foo">4</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::192.9.5.5]/ipng">5</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[::FFFF:129.144.52.38]:80/index.html">6</a></li>
 +<li><a rel="mw:ExtLink" class="external text" href="http://[2010:836B:4179::836B:4179]">7</a></li></ul>
  !! end
  
  !! test
@@@ -6186,15 -5853,6 +6186,15 @@@ Normal text. '''''Bold italic text.''''
  </p>
  !! end
  
 +!! test
 +Quotes wrapping HTML table
 +!! wikitext
 +'''<table><tr><td>hi</td></tr></table>'''
 +!! html/php+tidy
 +<b><table><tbody><tr><td>hi</td></tr></tbody></table></b>
 +!! html/parsoid
 +<b><table data-parsoid='{"stx":"html"}'><tbody><tr data-parsoid='{"stx":"html"}'><td data-parsoid='{"stx":"html"}'>hi</td></tr></tbody></table></b>
 +!! end
  
  # Parsoid inserts an empty bold tag pair at the end of the line, that the PHP
  # parser strips. The wikitext contains just the first half of the bold
@@@ -6273,8 -5931,6 +6273,8 @@@ parsoid=wt2htm
  
  !! end
  
 +# Note that the PHP parser output appears to be broken when the table
 +# end tag is not separated by a space from the style attribute
  !! test
  A table with stray table end tags on start tag line (wt2html)
  !! options
@@@ -6293,22 -5949,7 +6293,22 @@@ parsoid=wt2htm
  {|style="color: red;" |} id="foo"
  |foo
  |}
 -!! html
 +!! html/php+tidy
 +<table style="&quot;color:">
 +
 +</table><table style="color: red;">
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +<table style="&quot;color:" id="foo">
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +<table style="color: red;" id="foo">
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +!! html/parsoid
  <table style="color: red;"></table>
  
  <table style="color: red;">
@@@ -6347,31 -5988,31 +6347,31 @@@ A table with no data (take 2
  A table with nothing but a caption
  !! wikitext
  {|
 -|+ caption
 +|+caption
  |}
  !! html/php
  <table>
 -<caption> caption
 +<caption>caption
  </caption><tr><td></td></tr></table>
  
  !! html/parsoid
 -<table><caption> caption</caption></table>
 +<table><caption>caption</caption></table>
  !! end
  
  !! test
  A table with caption with default-spaced attributes and a table row
  !! wikitext
  {|
 -|+ style="color: red;" | caption1
 +|+ style="color: red;" |caption1
  |-
 -| foo
 +|foo
  |}
  !! html
  <table>
 -<caption style="color: red;"> caption1
 +<caption style="color: red;">caption1
  </caption>
  <tr>
 -<td> foo
 +<td>foo
  </td></tr></table>
  
  !! end
@@@ -6381,18 -6022,18 +6381,18 @@@ A table with captions with non-default 
  !! wikitext
  {|
  |+style="color: red;"|caption2
 -|+ style="color: red;"| caption3
 +|+ style="color: red;"|caption3
  |-
 -| foo
 +|foo
  |}
  !! html
  <table>
  <caption style="color: red;">caption2
  </caption>
 -<caption style="color: red;"> caption3
 +<caption style="color: red;">caption3
  </caption>
  <tr>
 -<td> foo
 +<td>foo
  </td></tr></table>
  
  !! end
  Table td-cell syntax variations
  !! wikitext
  {|
 -| foo bar foo | baz
 -| foo bar foo || baz
 -| style='color:red;' | baz
 -| style='color:red;' || baz
 +|foo bar foo|baz
 +|foo bar foo||baz
 +|style='color:red;'|baz
 +|style='color:red;'||baz
  |}
  !! html
  <table>
  <tr>
 -<td> baz
 +<td>baz
  </td>
 -<td> foo bar foo </td>
 -<td> baz
 +<td>foo bar foo</td>
 +<td>baz
  </td>
 -<td style="color:red;"> baz
 +<td style="color:red;">baz
  </td>
 -<td> style='color:red;' </td>
 -<td> baz
 +<td>style='color:red;'</td>
 +<td>baz
  </td></tr></table>
  
  !! end
  Simple table
  !! wikitext
  {|
 -| 1 || 2
 +|1||2
  |-
 -| 3 || 4
 +|3||4
  |}
  !! html
  <table>
  <tr>
 -<td> 1 </td>
 -<td> 2
 +<td>1</td>
 +<td>2
  </td></tr>
  <tr>
 -<td> 3 </td>
 -<td> 4
 +<td>3</td>
 +<td>4
  </td></tr></table>
  
  !! end
  Simple table but with multiple dashes for row wikitext
  !! wikitext
  {|
 -| foo
 +|foo
  |-----
 -| bar
 +|bar
  |}
  !! html
  <table>
  <tr>
 -<td> foo
 +<td>foo
  </td></tr>
  <tr>
 -<td> bar
 +<td>bar
  </td></tr></table>
  
  !! end
@@@ -6468,67 -6109,67 +6468,67 @@@ Multiplication tabl
  {| border="1" cellpadding="2"
  |+Multiplication table
  |-
 -! &times; !! 1 !! 2 !! 3
 +!&times;!!1!!2!!3
  |-
 -! 1
 -| 1 || 2 || 3
 +!1
 +|1||2||3
  |-
 -! 2
 -| 2 || 4 || 6
 +!2
 +|2||4||6
  |-
 -! 3
 -| 3 || 6 || 9
 +!3
 +|3||6||9
  |-
 -! 4
 -| 4 || 8 || 12
 +!4
 +|4||8||12
  |-
 -! 5
 -| 5 || 10 || 15
 +!5
 +|5||10||15
  |}
  !! html
  <table border="1" cellpadding="2">
  <caption>Multiplication table
  </caption>
  <tr>
 -<th> &#215; </th>
 -<th> 1 </th>
 -<th> 2 </th>
 -<th> 3
 +<th>&#215;</th>
 +<th>1</th>
 +<th>2</th>
 +<th>3
  </th></tr>
  <tr>
 -<th> 1
 +<th>1
  </th>
 -<td> 1 </td>
 -<td> 2 </td>
 -<td> 3
 +<td>1</td>
 +<td>2</td>
 +<td>3
  </td></tr>
  <tr>
 -<th> 2
 +<th>2
  </th>
 -<td> 2 </td>
 -<td> 4 </td>
 -<td> 6
 +<td>2</td>
 +<td>4</td>
 +<td>6
  </td></tr>
  <tr>
 -<th> 3
 +<th>3
  </th>
 -<td> 3 </td>
 -<td> 6 </td>
 -<td> 9
 +<td>3</td>
 +<td>6</td>
 +<td>9
  </td></tr>
  <tr>
 -<th> 4
 +<th>4
  </th>
 -<td> 4 </td>
 -<td> 8 </td>
 -<td> 12
 +<td>4</td>
 +<td>8</td>
 +<td>12
  </td></tr>
  <tr>
 -<th> 5
 +<th>5
  </th>
 -<td> 5 </td>
 -<td> 10 </td>
 -<td> 15
 +<td>5</td>
 +<td>10</td>
 +<td>15
  </td></tr></table>
  
  !! end
  Accept "||" in table headings
  !! wikitext
  {|
 -!h1 || h2
 +!h1||h2
  |}
  !! html
  <table>
  <tr>
 -<th>h1 </th>
 -<th> h2
 +<th>h1</th>
 +<th>h2
  </th></tr></table>
  
  !! end
  Accept "!!" in table data
  !! wikitext
  {|
 -| Foo!! ||
 +|Foo!!||
  |}
  !! html
  <table>
  <tr>
 -<td> Foo!! </td>
 +<td>Foo!!</td>
  <td>
  </td></tr></table>
  
  Accept "||" in indented table headings
  !! wikitext
  :{|
 -!h1 || h2
 +!h1||h2
  |}
  !! html
  <dl><dd><table>
  <tr>
 -<th>h1 </th>
 -<th> h2
 +<th>h1</th>
 +<th>h2
  </th></tr></table></dd></dl>
  
  !! end
@@@ -6646,15 -6287,15 +6646,15 @@@ Accept "!!" in table data of mixed wiki
  Accept empty attributes in td/th cells (td/th cells starting with leading ||)
  !! wikitext
  {|
 -!| h1
 -|| a
 +!|h1
 +||a
  |}
  !! html
  <table>
  <tr>
 -<th> h1
 +<th>h1
  </th>
 -<td> a
 +<td>a
  </td></tr></table>
  
  !! end
@@@ -6664,13 -6305,13 +6664,13 @@@ Accept "| !" at start of line in table
  !! wikitext
  {|
  |-
 -| !style="color:red" | bar
 +|!style="color:red"|bar
  |}
  !! html
  <table>
  
  <tr>
 -<td> bar
 +<td>bar
  </td></tr></table>
  
  !!end
@@@ -6683,8 -6324,8 +6683,8 @@@ Allow +/- in 2nd and later cells in a r
  |style='color:red;'|+1
  |style='color:blue;'|-1
  |-
 -| 1 || 2 || 3
 -| 1 ||+2 ||-3
 +|1||2||3
 +|1||+2||-3
  |-
  | +1
  | -1
  <td style="color:blue;">-1
  </td></tr>
  <tr>
 -<td> 1 </td>
 -<td> 2 </td>
 -<td> 3
 +<td>1</td>
 +<td>2</td>
 +<td>3
  </td>
 -<td> 1 </td>
 -<td>+2 </td>
 +<td>1</td>
 +<td>+2</td>
  <td>-3
  </td></tr>
  <tr>
 -<td> +1
 +<td>+1
  </td>
 -<td> -1
 +<td>-1
  </td></tr></table>
  
  !!end
  Table rowspan
  !! wikitext
  {| border=1
 -| Cell 1, row 1
 -|rowspan=2| Cell 2, row 1 (and 2)
 -| Cell 3, row 1
 +|Cell 1, row 1
 +|rowspan=2|Cell 2, row 1 (and 2)
 +|Cell 3, row 1
  |-
 -| Cell 1, row 2
 -| Cell 3, row 2
 +|Cell 1, row 2
 +|Cell 3, row 2
  |}
  !! html
  <table border="1">
  <tr>
 -<td> Cell 1, row 1
 +<td>Cell 1, row 1
  </td>
 -<td rowspan="2"> Cell 2, row 1 (and 2)
 +<td rowspan="2">Cell 2, row 1 (and 2)
  </td>
 -<td> Cell 3, row 1
 +<td>Cell 3, row 1
  </td></tr>
  <tr>
 -<td> Cell 1, row 2
 +<td>Cell 1, row 2
  </td>
 -<td> Cell 3, row 2
 +<td>Cell 3, row 2
  </td></tr></table>
  
  !! end
@@@ -6758,7 -6399,7 +6758,7 @@@ Nested tabl
  !! html
  <table border="1">
  <tr>
 -<td> &#945;
 +<td>&#945;
  </td>
  <td>
  <table bgcolor="#ABCDEF" border="2">
@@@ -6792,9 -6433,9 +6792,9 @@@ Invalid attributes in table cell (T3830
  Table cell attributes: Pipes protected by nowikis should be treated as a plain character
  !! wikitext
  {|
 -| title="foo" |bar
 -| title="foo<nowiki>|</nowiki>" |bar
 -| title="foo<nowiki>|</nowiki>" bar
 +|title="foo" |bar
 +|title="foo<nowiki>|</nowiki>" |bar
 +|title="foo<nowiki>|</nowiki>" bar
  |}
  !! html/php
  <table>
  </td>
  <td title="foo&#124;">bar
  </td>
 -<td> title="foo|" bar
 +<td>title="foo|" bar
  </td></tr></table>
  
  !! html/parsoid
@@@ -6843,17 -6484,17 +6843,17 @@@ parsoid=wt2html,html2htm
  Element attributes with double ! should not be broken up by <th>
  !! wikitext
  {|
 -! hi <div class="!!">ha</div> ho
 +!hi <div class="!!">ha</div> ho
  |}
  !! html/php
  <table>
  <tr>
 -<th> hi <div class="!!">ha</div> ho
 +<th>hi <div class="!!">ha</div> ho
  </th></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><th> hi <div class="!!" data-parsoid='{"stx":"html"}'>ha</div> ho</th></tr>
 +<tbody><tr><th>hi <div class="!!" data-parsoid='{"stx":"html"}'>ha</div> ho</th></tr>
  </tbody></table>
  !! end
  
  ! and || in element attributes should not be parsed as <th>/<td>
  !! wikitext
  {|
 -| <div style="color: red !important;" data-contrived="put this here ||">hi</div>
 +|<div style="color: red !important;" data-contrived="put this here ||">hi</div>
  |}
  !! html/php
  <table>
  <tr>
 -<td> <div style="color: red !important;" data-contrived="put this here &#124;&#124;">hi</div>
 +<td><div style="color: red !important;" data-contrived="put this here &#124;&#124;">hi</div>
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><td> <div style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"stx":"html"}'>hi</div></td></tr>
 +<tbody><tr><td><div style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"stx":"html"}'>hi</div></td></tr>
  </tbody></table>
  !! end
  
  parsoid=wt2html
  !! wikitext
  {|
 -| style="color: red !important;" data-contrived="put this here ||" | foo
 +|style="color: red !important;" data-contrived="put this here ||"|foo
  |}
  !! html/php
  <table>
  <tr>
 -<td> style="color: red !important;" data-contrived="put this here </td>
 -<td> foo
 +<td>style="color: red !important;" data-contrived="put this here</td>
 +<td>foo
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><td> style="color: red !important;" data-contrived="put this here </td><td data-parsoid='{"stx":"row","a":{"\"":null},"sa":{"\"":""},"autoInsertedEnd":true}'> foo</td></tr>
 +<tbody><tr><td>style="color: red !important;" data-contrived="put this here</td><td data-parsoid='{"stx":"row","a":{"\"":null},"sa":{"\"":""},"autoInsertedEnd":true}'>foo</td></tr>
  </tbody></table>
  !! end
  
@@@ -6907,7 -6548,7 +6907,7 @@@ parsoid=wt2html,html2htm
  <p>ho"&gt;ha&lt;/div&gt;
  </p>
  !! html/parsoid
 -<span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha&lt;/div>"}},"i":0}}]}'>ho">ha</span>
 +<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha&lt;/div>"}},"i":0}}]}'>ho">ha</p>
  !! end
  
  !! test
@@@ -6925,9 -6566,9 +6925,9 @@@ Don't break on | in extension attribut
  
  <references />
  !! html/parsoid
 -<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
 +<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
  
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Main_Page#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Parser_test#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
  !! end
  
  ## We don't support roundtripping of these attributes in Parsoid.
@@@ -6939,22 -6580,22 +6939,22 @@@ Invalid text in table attributes shoul
  parsoid=wt2html
  !! wikitext
  {| <span>boo</span> style='border:1px solid black'
 -|  <span>boo</span> style='color:blue'  | 1
 -|<span>boo</span> style='color:blue'| 2
 +|  <span>boo</span> style='color:blue'  |1
 +|<span>boo</span> style='color:blue'|2
  |}
  !! html/php
  <table style="border:1px solid black">
  <tr>
 -<td style="color:blue"> 1
 +<td style="color:blue">1
  </td>
 -<td style="color:blue"> 2
 +<td style="color:blue">2
  </td></tr></table>
  
  !! html/parsoid
  <table style="border:1px solid black">
  <tr>
 -<td style="color:blue"> 1</td>
 -<td style="color:blue"> 2</td>
 +<td style="color:blue">1</td>
 +<td style="color:blue">2</td>
  </tr>
  </table>
  !! end
@@@ -6976,8 -6617,8 +6976,8 @@@ parsoid=
  |}
  !! wikitext/edited
  {| <span>boo</span> style='border:1px solid black'
 -|  <span>boo</span> style='color:blue'  |abc
 -|<span>boo</span> style='color:blue'|xyz
 +|  <span>boo</span> style='color:blue'  | abc
 +|<span>boo</span> style='color:blue'| xyz
  |}
  !! end
  
  </td>
  <td style="color:red;">Foo
  </td>
 -<td> style="color:red;"</td>
 +<td>style="color:red;"</td>
  <td>Bar
  </td>
  <td style="color:red;">Foo
@@@ -7100,9 -6741,9 +7100,9 @@@ T107652: <ref>s in templates that also 
  <references />
  !! html/parsoid
  <table>
 -<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
 +<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
  </tbody></table>
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
  !! end
  
  !! test
@@@ -7113,14 -6754,14 +7113,14 @@@ parsoid=wt2html,html2htm
  {|
  |-
  
 -! foo
 +!foo
  |}
  !! html/*
  <table>
  
  
  <tr>
 -<th> foo
 +<th>foo
  </th></tr></table>
  
  !! end
@@@ -7133,14 -6774,14 +7133,14 @@@ parsoid=wt2html,html2htm
  {|
  
  |-
 -| foo
 +|foo
  |}
  !! html/*
  <table>
  
  
  <tr>
 -<td> foo
 +<td>foo
  </td></tr></table>
  
  !! end
@@@ -7151,17 -6792,17 +7151,17 @@@ Table attributes with empty valu
  parsoid=wt2html,html2html
  !! wikitext
  {|
 -| style=| hello
 +| style=|hello
  |}
  !! html/php
  <table>
  <tr>
 -<td style=""> hello
 +<td style="">hello
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><td style=""> hello</td></tr>
 +<tbody><tr><td style="">hello</td></tr>
  </tbody></table>
  !! end
  
@@@ -7170,7 -6811,7 +7170,7 @@@ Wikitext table with a lot of comment
  !! wikitext
  {|
  <!-- c0 -->
 -| foo
 +|foo
  <!-- c1 -->
  |-<!-- c2 -->
  <!-- c3 -->
  !! html
  <table>
  <tr>
 -<td> foo
 +<td>foo
  </td></tr>
  <tr>
  <td>
@@@ -7193,18 -6834,18 +7193,18 @@@ Wikitext table comments represented in 
  !! wikitext
  {|<!--c1--><!--c2-->
  |-<!--c3-->
 -| x
 +|x
  |}
  !! html/php+tidy
  <table>
  
  <tbody><tr>
 -<td> x
 +<td>x
  </td></tr></tbody></table>
  !! html/parsoid
  <table><!--c1--><!--c2-->
  <tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'><!--c3-->
 -<td data-parsoid='{"autoInsertedEnd":true}'> x</td></tr>
 +<td data-parsoid='{"autoInsertedEnd":true}'>x</td></tr>
  </tbody></table>
  !! end
  
  Table cell with a single comment
  !! wikitext
  {|
 -| <!-- c1 -->
 -| a
 +|<!-- c1 -->
 +|a
  |}
  !! html
  <table>
  <tr>
  <td>
  </td>
 -<td> a
 +<td>a
  </td></tr></table>
  
  !! end
@@@ -7248,21 -6889,21 +7248,21 @@@ Table-cell after a comment-only-empty-l
  {|
  |a
  <!--c1-->
 -<!--c2-->| b
 +<!--c2-->|b
  |}
  !! html
  <table>
  <tr>
  <td>a
  </td>
 -<td> b
 +<td>b
  </td></tr></table>
  
  !! html/parsoid
  <table>
  <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'>a</td>
  <!--c1-->
 -<!--c2--><td data-parsoid='{"autoInsertedEnd":true}'> b</td></tr>
 +<!--c2--><td data-parsoid='{"autoInsertedEnd":true}'>b</td></tr>
  </tbody></table>
  
  !! end
  Build table with {{!}}
  !! wikitext
  {{{!}} class="wikitable"
 -! header
 -! second header
 +!header
 +!second header
  {{!}}- style="color:red;"
 -{{!}} data {{!}}{{!}} style="color:red;" {{!}} second data
 +{{!}}data{{!}}{{!}} style="color:red;" {{!}}second data
  {{!}}}
  !! html
  <table class="wikitable">
  <tr>
 -<th> header
 +<th>header
  </th>
 -<th> second header
 +<th>second header
  </th></tr>
  <tr style="color:red;">
 -<td> data </td>
 -<td style="color:red;"> second data
 +<td>data</td>
 +<td style="color:red;">second data
  </td></tr></table>
  
  !! end
  Build table with pipe as data
  !! wikitext
  {| class="wikitable"
 -! header
 -! second header
 +!header
 +!second header
  |- style="color:red;"
 -| data || style="color:red;" | second data
 +|data|| style="color:red;" |second data
  |-
 -| style="color:red;" | data with | || style="color:red;" | second data with |
 +| style="color:red;" |data with | || style="color:red;" | second data with |
  |-
 -|| data with | ||| second data with |
 +||data with | |||second data with |
  |}
  !! html
  <table class="wikitable">
  <tr>
 -<th> header
 +<th>header
  </th>
 -<th> second header
 +<th>second header
  </th></tr>
  <tr style="color:red;">
 -<td> data </td>
 -<td style="color:red;"> second data
 +<td>data</td>
 +<td style="color:red;">second data
  </td></tr>
  <tr>
 -<td style="color:red;"> data with | </td>
 -<td style="color:red;"> second data with |
 +<td style="color:red;">data with |</td>
 +<td style="color:red;">second data with |
  </td></tr>
  <tr>
 -<td> data with | </td>
 -<td> second data with |
 +<td>data with |</td>
 +<td>second data with |
  </td></tr></table>
  
  !! end
  Build table with wikilink
  !! wikitext
  {| class="wikitable"
 -! header || second header
 +!header||second header
  |- style="color:red;"
 -| data [[Main Page|linktext]] || second data [[Main Page|linktext]]
 +|data [[Main Page|linktext]]||second data [[Main Page|linktext]]
  |-
 -| data || second data [[Main Page|link|text with pipe]]
 +|data||second data [[Main Page|link|text with pipe]]
  |}
  !! html
  <table class="wikitable">
  <tr>
 -<th> header </th>
 -<th> second header
 +<th>header</th>
 +<th>second header
  </th></tr>
  <tr style="color:red;">
 -<td> data <a href="/wiki/Main_Page" title="Main Page">linktext</a> </td>
 -<td> second data <a href="/wiki/Main_Page" title="Main Page">linktext</a>
 +<td>data <a href="/wiki/Main_Page" title="Main Page">linktext</a></td>
 +<td>second data <a href="/wiki/Main_Page" title="Main Page">linktext</a>
  </td></tr>
  <tr>
 -<td> data </td>
 -<td> second data <a href="/wiki/Main_Page" title="Main Page">link|text with pipe</a>
 +<td>data</td>
 +<td>second data <a href="/wiki/Main_Page" title="Main Page">link|text with pipe</a>
  </td></tr></table>
  
  !! end
@@@ -7369,11 -7010,10 +7369,11 @@@ Wikitext table with html-syntax ro
  <td>foo</td></tr></tbody></table>
  !! end
  
 +## Remex doesn't account for fostered content.
  !! test
  Fostered content in tables: Plain text
  !! options
 -parsoid=wt2html,html2html
 +parsoid=wt2html
  !! wikitext
  {|
  |-
  a
  <table></table>
  !! html/parsoid
 -<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>a</p><table>
 -<tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
 -
 -</tr></tbody></table>
 +<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
 +a</p>
 +<table>
 +<tbody><tr class="mw-empty-elt" data-parsoid='{"startTagSrc":"|-"}'></tr></tbody></table>
  !! end
  
  !! test
@@@ -7429,20 -7069,20 +7429,20 @@@ Template generated table cell with attr
  !! wikitext
  {|
  |-
 -{{table_attribs_4}} || a || b
 +{{table_attribs_4}} ||a||b
  |}
  !! html/php+tidy
  <table>
  
  <tbody><tr>
 -<td style="background-color:#DC241f;" width="10px"> </td>
 -<td> a </td>
 -<td> b
 +<td style="background-color:#DC241f;" width="10px"></td>
 +<td>a</td>
 +<td>b
  </td></tr></tbody></table>
  !! html/parsoid
  <table>
  <tbody><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
 -<td style="background-color:#DC241f;" width="10px" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"table_attribs_4","href":"./Template:Table_attribs_4"},"params":{},"i":0}}," || a || b"]}'> </td><td about="#mwt1"> a </td><td about="#mwt1"> b</td></tr>
 +<td style="background-color:#DC241f;" width="10px" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":[{"template":{"target":{"wt":"table_attribs_4","href":"./Template:Table_attribs_4"},"params":{},"i":0}}," ||a||b"]}'></td><td about="#mwt1">a</td><td about="#mwt1">b</td></tr>
  !! end
  
  !! test
@@@ -7489,29 -7129,41 +7489,29 @@@ parsoid=html2w
  '''quux'''
  !! end
  
 -!! test
 -Parsoid: newline inducing block nodes don't suppress <nowiki>
 -!! options
 -parsoid=html2wt
 -!! html/parsoid
 - a<h1>foo</h1>
 -!! wikitext
 -<nowiki> </nowiki>a
 -
 -= foo =
 -!! end
 -
  !! test
  Parsoid: Row-syntax table headings followed by comment & table cells
  !! options
  parsoid=wt2html,wt2wt
  !! wikitext
  {|
 -! foo || bar
 -<!-- foo -->  || baz || quux
 +!foo||bar
 +<!-- foo -->  ||baz||quux
  |}
  !! html/php
  <table>
  <tr>
 -<th> foo </th>
 -<th> bar
 +<th>foo</th>
 +<th>bar
  </th>
 -<td> baz </td>
 -<td> quux
 +<td>baz</td>
 +<td>quux
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><th> foo </th><th> bar
 -<!-- foo -->  </th><td> baz </td><td> quux</td></tr>
 +<tbody><tr><th>foo</th><th>bar
 +<!-- foo --></th><td> baz </td><td>quux</td></tr>
  </tbody></table>
  !! end
  
@@@ -7539,7 -7191,6 +7539,7 @@@ fo
  </tbody></table>
  !!end
  
 +# Note: PHP parser omits empty rows
  !! test
  Tables: Digest broken attributes on table and tr tag
  !! options
@@@ -7549,12 -7200,7 +7549,12 @@@ parsoid=wt2htm
  |- || || ++ --
  |- > [
  |}
 -!! html
 +!! html/php+tidy
 +<table>
 +
 +
 +</table>
 +!! html/parsoid
  <table>
  <tbody>
  <tr class='mw-empty-elt'></tr>
  </tbody></table>
  !! end
  
 +!! test
 +Table with missing opening <tr> tag
 +!! options
 +parsoid=wt2html,wt2wt
 +!! wikitext
 +<table>
 +<td>foo</td>
 +</tr>
 +</table>
 +!! html+tidy
 +<table>
 +<tbody><tr><td>foo</td>
 +</tr>
 +</tbody></table>
 +!! end
 +
  # T137406: Whitespace in the HTML
  !! test
  1. Generate correct wikitext for tables with thead/tbody/tfoot
@@@ -7666,10 -7296,101 +7666,10 @@@ parsoid=html2w
  !! end
  
  !! test
 -Testing serialization after deletion in references
 -!! options
 -parsoid={
 -  "modes": ["wt2wt"],
 -  "changes": [
 -    ["#x", "remove"]
 -  ]
 -}
 -!! wikitext
 -hi <ref><div id="x">ho</div></ref>
 -
 -<references />
 -!! wikitext/edited
 -hi <ref></ref>
 -
 -<references />
 -!! end
 -
 -!!test
 -Testing serialization after deletion of table cells
 -!!options
 -parsoid={
 -  "modes": ["wt2wt", "selser"],
 -  "changes": [
 -    ["#x", "remove"]
 -  ]
 -}
 -!!wikitext
 -{|
 -!h1 !!h2 !!h3
 -| id="x" |c1 {{!}}{{!}}{{!}}c2 |||c3
 -|}
 -!! wikitext/edited
 -{|
 -!h1 !!h2 !!h3
 -|c2 |||c3
 -|}
 -!!end
 -
 -!! test
 -Testing selser after addition of new row before first row (T125419)
 -!! options
 -parsoid={
 -  "modes": ["wt2wt", "selser"],
 -  "changes": [
 -    [ "tr", "before", "<tr><td>X</td></tr>" ]
 -  ]
 -}
 -!! wikitext
 -{|
 -|a
 -|}
 -!! wikitext/edited
 -{|
 -|X
 -|-
 -|a
 -|}
 -!! end
 -
 -!! test
 -Serialize new table rows in a HTML table using HTML tags
 -!! options
 -parsoid={
 -  "modes": ["wt2wt", "selser"],
 -  "changes": [
 -    [ "tr", "before", "<tr><td>X</td></tr>" ]
 -  ]
 -}
 -!! wikitext
 -<table><tr><td>a</td></tr></table>
 -!! wikitext/edited
 -<table><tr><td>X</td></tr><tr><td>a</td></tr></table>
 -!! end
 -
 -!! test
 -Serialize new table cells in a HTML row using HTML tags
 -!! options
 -parsoid={
 -  "modes": ["wt2wt", "selser"],
 -  "changes": [
 -    [ "td", "before", "<td>X</td>" ]
 -  ]
 -}
 -!! wikitext
 -<table><tr><td>a</td></tr></table>
 -!! wikitext/edited
 -<table><tr><td>X</td><td>a</td></tr></table>
 -!! end
 -
 -!! test
 -Wikitext tables can be nested inside HTML tables
 +Wikitext tables can be nested inside HTML tables
  !! options
  parsoid=html2wt
 -!! html
 +!! html/parsoid
  <table data-parsoid='{"stx":"html"}'>
  <tr><td>
  <table>
  |}
  </td></tr>
  </table>
 -!! end
 -
 -!! test
 -Serialize wikitext list items as HTML list items when embedded in a HTML list
 -!! options
 -parsoid=html2wt
 -!! html
 -<ul data-parsoid='{"stx": "html"}'>
 -<li data-parsoid='{}'>a</li>
 -<li>b</li>
 -</ul>
 -!! wikitext
 -<ul>
 -<li>a</li>
 -<li>b</li>
 -</ul>
 -!! end
 -
 -# SSS FIXME: Is this actually a good thing given the
 -# odd nested list output that is generated by MW?
 -# <ul><li>foo<ul>..</ul></li></ul> instead of
 -# <ul><li>foo</li><ul>..</ul></ul>
 -!! test
 -Wikitext lists can be nested inside HTML lists
 -!! options
 -parsoid=html2wt
 -!! html
 -<ul data-parsoid='{"stx": "html"}'>
 -<li data-parsoid='{"stx": "html"}'>a
 -<ul><li>b</li></ul>
 -</li>
 -</ul>
 -
 -<ul data-parsoid='{"stx": "html"}'>
 -<li>x
 -<ul><li>y</li></ul>
 -</li>
 -</ul>
 -!! wikitext
 -<ul>
 -<li>a
 -* b
 -</li>
 -</ul>
 -
 -<ul>
 -<li>x
 -* y
 -</li>
 -</ul>
 +!! html/php+tidy
 +<table>
 +<tbody><tr><td>
 +<table>
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +</td></tr>
 +</tbody></table>
  !! end
  
  ###
@@@ -8044,8 -7806,6 +8044,8 @@@ Link containing % as a double hex seque
  ## Example for such a section: == < ==
  !! test
  Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors
 +!! options
 +title=[[Main Page]]
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
@@@ -8089,31 -7849,6 +8089,31 @@@ Link containing an equals sig
  <p><a rel="mw:WikiLink" href="./Special:BookSources/isbn=4-00-026157-6" title="Special:BookSources/isbn=4-00-026157-6">Special:BookSources/isbn=4-00-026157-6</a></p>
  !! end
  
 +!! article
 +Foo & bar
 +!! text
 +Just a test of an article title containing an ampersand
 +!! endarticle
 +
 +!! test
 +Link containing an ampersand
 +!! wikitext
 +[[Foo & bar]]
 +
 +[[Foo &amp; bar]]
 +
 +[[Foo &amp;amp; bar]]
 +!! html/php+tidy
 +<p><a href="/wiki/Foo_%26_bar" title="Foo &amp; bar">Foo &amp; bar</a>
 +</p><p><a href="/wiki/Foo_%26_bar" title="Foo &amp; bar">Foo &amp; bar</a>
 +</p><p>[[Foo &amp;amp; bar]]
 +</p>
 +!! html/parsoid
 +<p><a rel="mw:WikiLink" href="./Foo_&amp;_bar" title="Foo &amp; bar">Foo &amp; bar</a></p>
 +<p><a rel="mw:WikiLink" href="./Foo_&amp;_bar" title="Foo &amp; bar" data-parsoid='{"stx":"simple","a":{"href":"./Foo_&amp;_bar"},"sa":{"href":"Foo &amp;amp; bar"}}'>Foo &amp; bar</a></p>
 +<p>[[Foo <span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp; bar]]</p>
 +!! end
 +
  !! article
  Foo~bar
  !! text
@@@ -8594,32 -8329,27 +8594,32 @@@ parsoid=html2w
  1. Interaction of linktrail and template encapsulation
  !! wikitext
  {{echo|[[Foo]]}}l
 +!! html/php+tidy
 +<p><a href="/wiki/Foo" title="Foo">Fool</a>
 +</p>
  !! html/parsoid
  <p><a rel="mw:WikiLink" href="./Foo" title="Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Foo]]"}},"i":0}},"l"]}'>Fool</a></p>
  !! end
  
  !! test
  2. Interaction of linktrail and template encapsulation
 -!! options
 -parsoid
  !! wikitext
  {{echo|Some [[Fool]]}}s
 -!! html
 +!! html/php+tidy
 +<p>Some <a href="/index.php?title=Fool&amp;action=edit&amp;redlink=1" class="new" title="Fool (page does not exist)">Fools</a>
 +</p>
 +!! html/parsoid
  <p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Some [[Fool]]"}},"i":0}},"s"]}' data-parsoid='{"pi":[[{"k":"1"}]]}'>Some </span><a rel="mw:WikiLink" href="./Fool" title="Fool" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Fool"},"sa":{"href":"Fool"},"tail":"s"}'>Fools</a></p>
  !! end
  
  !! test
  3. Interaction of linktrail and template encapsulation
 -!! options
 -parsoid
  !! wikitext
  {{echo|Some [[Fool]]s are '''bold and foolish'''}}
 -!! html
 +!! html/php+tidy
 +<p>Some <a href="/index.php?title=Fool&amp;action=edit&amp;redlink=1" class="new" title="Fool (page does not exist)">Fools</a> are <b>bold and foolish</b>
 +</p>
 +!! html/parsoid
  <p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Some [[Fool]]s are &#39;&#39;&#39;bold and foolish&#39;&#39;&#39;"}},"i":0}}]}' data-parsoid='{"pi":[[{"k":"1"}]]}'>Some <a rel="mw:WikiLink" href="./Fool" title="Fool" data-parsoid='{"stx":"simple","a":{"href":"./Fool"},"sa":{"href":"Fool"},"tail":"s"}'>Fools</a> are <b>bold and foolish</b></p>
  !! end
  
@@@ -8799,13 -8529,15 +8799,13 @@@ parsoid=wt2html,wt2w
  !! wikitext
  *[[Wikipedia:ro:Olteni&#0355;a]]
  *[[Wikipedia:ro:Olteni&#355;a]]
 -!! html
 +!! html/php
  <ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li>
  <li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li></ul>
  
  !! html/php+tidy
 -<ul>
 -<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a></li>
 -<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a></li>
 -</ul>
 +<ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li>
 +<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li></ul>
  !! html/parsoid
  <ul>
  <li><a rel="mw:WikiLink/Interwiki" href="http://en.wikipedia.org/wiki/ro:Olteniţa" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a></li>
@@@ -8824,8 -8556,6 +8824,8 @@@ Interwiki link with fragment (T4130
  
  !! test
  Link scenarios with escaped fragments
 +!! options
 +title=[[Main Page]]
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
@@@ -8914,7 -8644,7 +8914,7 @@@ Interwiki links that cannot be represen
  !! html/parsoid
  <p><a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?ok" title="meatball:ok">meatball:ok</a>
  <a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?ok#foo" title="meatball:ok">ok with fragment</a>
 -<a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?ok_as_well?" title="meatball:ok as well?">ok ending with ? mark</a>
 +<a rel="mw:WikiLink/Interwiki" href="http://www.usemod.com/cgi-bin/mb.pl?ok_as_well%3F" title="meatball:ok as well?">ok ending with ? mark</a>
  <a rel="mw:ExtLink" class="external text" href="http://de.wikipedia.org/wiki/Foo?action=history">has query</a>
  <a rel="mw:ExtLink" class="external text" href="http://de.wikipedia.org/wiki/#foo">is just fragment</a></p>
  !! end
@@@ -8997,17 -8727,6 +8997,17 @@@ parsoid=wt2html,wt2wt,html2htm
  <p><a rel="mw:WikiLink" href="./Foo" title="Foo">local:local:local:local:mi:local:Foo</a></p>
  !! end
  
 +!! test
 +Interwiki link with percent encoded target
 +!! wikitext
 +[[:es:Nueva Guip%C3%BAzcoa|Nueva Guipúzcoa]]
 +!! html/php
 +<p><a href="http://es.wikipedia.org/wiki/Nueva_Guip%C3%BAzcoa" class="extiw" title="es:Nueva Guipúzcoa">Nueva Guipúzcoa</a>
 +</p>
 +!! html/parsoid
 +<p><a rel="mw:WikiLink/Interwiki" href="http://es.wikipedia.org/wiki/Nueva%20Guipúzcoa" title="es:Nueva Guipúzcoa" data-parsoid='{"stx":"piped","a":{"href":"http://es.wikipedia.org/wiki/Nueva%20Guipúzcoa"},"sa":{"href":":es:Nueva Guip%C3%BAzcoa"},"isIW":true}'>Nueva Guipúzcoa</a></p>
 +!! end
 +
  ###
  ### Interlanguage links
  ### Language links (so that searching for '### language' matches..)
@@@ -9249,14 -8968,6 +9249,14 @@@ parsoid=wt2html,wt2w
  <p><a rel="mw:WikiLink" href="./Constructor:foo" title="Constructor:foo" data-parsoid='{"stx":"simple","a":{"href":"./Constructor:foo"},"sa":{"href":"constructor:foo"}}'>constructor:foo</a></p>
  !! end
  
 +!! test
 +Template parameter named "constructor"
 +!! wikitext
 +{{echo|  constructor =  |hi}}
 +!! html/parsoid
 +<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"constructor","named":true,"spc":["  "," ","","  "]},{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi"},"constructor":{"wt":""}},"i":0}}]}'>hi</p>
 +!! end
 +
  !! article
  ko:
  !! text
@@@ -9518,7 -9229,6 +9518,7 @@@ language=i
  Redirect syntax under text isn't considered a redirect
  !! wikitext
  some text
 +
  #redirect [[Main Page]]
  !! html/parsoid
  <p>some text</p>
@@@ -9541,9 -9251,9 +9541,9 @@@ Redirect followed by block on the same 
  !! options
  parsoid=wt2html
  !! wikitext
 -#REDIRECT [[Main Page]]<!-- haha -->== hi ==
 +#REDIRECT [[Main Page]]<!-- haha -->==hi==
  !! html/parsoid
 -<link rel="mw:PageProp/redirect" href="./Main_Page"/><!-- haha --><h2 id="hi"> hi </h2>
 +<link rel="mw:PageProp/redirect" href="./Main_Page"/><!-- haha --><h2 id="hi">hi</h2>
  !! end
  
  !! test
@@@ -9666,32 -9376,10 +9666,32 @@@ Handling html with a div self-closing t
  !! html/parsoid
  <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
  <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
 -<div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
 +<div title="" data-parsoid='{"stx":"html","autoInsertedEnd":true}'>
  <div title="bar" data-parsoid='{"stx":"html","selfClose":true}'></div>
  <div title="bar" data-parsoid='{"stx":"html","selfClose":true}'></div>
 -<div title="bar/" data-parsoid='{"stx":"html","autoInsertedEnd":true}'></div>
 +<div title="bar/" data-parsoid='{"stx":"html","autoInsertedEnd":true}'></div></div>
 +!! end
 +
 +!! test
 +Elements with solidus in various attribute positions
 +!! options
 +parsoid=wt2html,html2html
 +!! wikitext
 +<div cla/ss="123">ha</div>
 +
 +<div / class="123">ha</div>
 +
 +<div class= / "123">ha</div>
 +!! html/php+tidy
 +<div>ha</div>
 +<div class="123">ha</div>
 +<div class="/">ha</div>
 +!! html/parsoid
 +<div data-parsoid='{"stx":"html","a":{"cla":null,"ss":null},"sa":{"cla":"","ss":"123"}}'>ha</div>
 +
 +<div class="123" data-parsoid='{"stx":"html"}'>ha</div>
 +
 +<div class="/" data-parsoid='{"stx":"html","a":{"\"123\"":null},"sa":{"\"123\"":""}}'>ha</div>
  !! end
  
  !! test
@@@ -9792,11 -9480,11 +9792,11 @@@ Horizontal ruler -- Supports content fo
  Common list
  !! wikitext
  *Common list
 -* item 2
 +*item 2
  *item 3
  !! html
  <ul><li>Common list</li>
 -<li> item 2</li>
 +<li>item 2</li>
  <li>item 3</li></ul>
  
  !! end
@@@ -9806,22 -9494,21 +9806,22 @@@ Numbered lis
  !! wikitext
  #Numbered list
  #item 2
 -# item 3
 +#item 3
  !! html
  <ol><li>Numbered list</li>
  <li>item 2</li>
 -<li> item 3</li></ol>
 +<li>item 3</li></ol>
  
  !! end
  
 +# the switch from level 3 to ordered should not introduce a newline between
  !! test
  Mixed list
  !! wikitext
  *Mixed list
 -*# with numbers
 -** and bullets
 -*# and numbers
 +*#with numbers
 +**and bullets
 +*#and numbers
  *bullets again
  **bullet level 2
  ***bullet level 3
  **#Number on level 3
  *#number level 2
  *Level 1
 -*** Level 3
 -#** Level 3, but ordered
 +***Level 3
 +#**Level 3, but ordered
  !! html
  <ul><li>Mixed list
 -<ol><li> with numbers</li></ol>
 -<ul><li> and bullets</li></ul>
 -<ol><li> and numbers</li></ol></li>
 +<ol><li>with numbers</li></ol>
 +<ul><li>and bullets</li></ul>
 +<ol><li>and numbers</li></ol></li>
  <li>bullets again
  <ul><li>bullet level 2
  <ul><li>bullet level 3
  <li>Number on level 3</li></ol></li></ul>
  <ol><li>number level 2</li></ol></li>
  <li>Level 1
 -<ul><li><ul><li> Level 3</li></ul></li></ul></li></ul>
 -<ol><li><ul><li><ul><li> Level 3, but ordered</li></ul></li></ul></li></ol>
 +<ul><li><ul><li>Level 3</li></ul></li></ul></li></ul>
 +<ol><li><ul><li><ul><li>Level 3, but ordered</li></ul></li></ul></li></ol>
  
  !! end
  
  !! test
  1. Nested mixed wikitext and html list
  !! wikitext
 -* hi
 -* <ul><li>ho</li></ul>
 -* hi
 -** ho
 +*hi
 +*<ul><li>ho</li></ul>
 +*hi
 +**ho
  !! html/php
 -<ul><li> hi</li>
 -<li> <ul><li>ho</li></ul></li>
 -<li> hi
 -<ul><li> ho</li></ul></li></ul>
 +<ul><li>hi</li>
 +<li><ul><li>ho</li></ul></li>
 +<li>hi
 +<ul><li>ho</li></ul></li></ul>
  
  !! html/parsoid
 -<ul><li> hi</li>
 -<li> <ul data-parsoid='{"stx":"html"}'><li data-parsoid='{"stx":"html"}'>ho</li></ul></li>
 -<li> hi
 -<ul><li> ho</li></ul></li></ul>
 +<ul><li>hi</li>
 +<li><ul data-parsoid='{"stx":"html"}'><li data-parsoid='{"stx":"html"}'>ho</li></ul></li>
 +<li>hi
 +<ul><li>ho</li></ul></li></ul>
  !! end
  
  !! test
  2. Nested mixed wikitext and html list (incompatible)
  !! wikitext
 -; hi
 -: {{echo|<li>ho</li>}}
 +;hi
 +:{{echo|<li>ho</li>}}
  !! html/php
 -<dl><dt> hi</dt>
 -<dd> <li>ho</li></dd></dl>
 +<dl><dt>hi</dt>
 +<dd><li>ho</li></dd></dl>
  
  !! html/parsoid
 -<dl><dt> hi</dt>
 -<dd> <li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>ho&lt;/li>"}},"i":0}}]}'>ho</li></dd></dl>
 +<dl><dt>hi</dt>
 +<dd><li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>ho&lt;/li>"}},"i":0}}]}'>ho</li></dd></dl>
  !! end
  
  !! test
@@@ -9955,35 -9642,33 +9955,35 @@@ Nested lists 6 (both elements empty
  !! test
  Nested lists 7 (skip initial nesting levels)
  !! wikitext
 -*** foo
 +***foo
  !! html
 -<ul><li><ul><li><ul><li> foo</li></ul></li></ul></li></ul>
 +<ul><li><ul><li><ul><li>foo</li></ul></li></ul></li></ul>
  
  !! end
  
  !! test
  Nested lists 8 (multiple nesting transitions)
  !! wikitext
 -* foo
 -*** bar
 -** baz
 -* boo
 +*foo
 +***bar
 +**baz
 +*boo
  !! html
 -<ul><li> foo
 -<ul><li><ul><li> bar</li></ul></li>
 -<li> baz</li></ul></li>
 -<li> boo</li></ul>
 +<ul><li>foo
 +<ul><li><ul><li>bar</li></ul></li>
 +<li>baz</li></ul></li>
 +<li>boo</li></ul>
  
  !! end
  
 +# XXX this test should be moved to citeParserTests, since it depends
 +# on the Cite extension, which is "built in" to Parsoid.
  !! test
  Nested lists 9 (extension interaction)
 -!! options
 -parsoid
  !! wikitext
  *<references />
 +!! html/php+tidy-DISABLED
 +<ul><li class="mw-empty-elt"></li></ul>
  !! html/parsoid
  <ul><li data-parsoid='{}'><ol class="mw-references references" typeof="mw:Extension/references" about="#mwt2" data-parsoid='{}' data-mw='{"name":"references","attrs":{}}'></ol></li></ul>
  !! end
  
  !! end
  
 +!! test
 +Nested lists 10 (list and span siblings: wt2wt regression)
 +!! wikitext
 +*a <span>x</span>
 +**b <span>y</span>
 +!! html/parsoid
 +<ul><li>a <span>x</span>
 +<ul><li>b <span>y</span></li></ul></li></ul>
 +!! end
 +
  !! test
  2. Lists with start-of-line-transparent tokens before bullets: Template close
  !! wikitext
  !! test
  List items are not parsed correctly following a <pre> block (T2785)
  !! wikitext
 -* <pre>foo</pre>
 -* <pre>bar</pre>
 -* zar
 +*<pre>foo</pre>
 +*<pre>bar</pre>
 +*zar
  !! html/php
 -<ul><li> <pre>foo</pre></li>
 -<li> <pre>bar</pre></li>
 -<li> zar</li></ul>
 +<ul><li><pre>foo</pre></li>
 +<li><pre>bar</pre></li>
 +<li>zar</li></ul>
  
  !! html/parsoid
 -<ul><li> <pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo"}}'>foo</pre></li>
 -<li> <pre typeof="mw:Extension/pre" about="#mwt4" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"bar"}}'>bar</pre></li>
 -<li> zar</li></ul>
 +<ul><li><pre typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo"}}'>foo</pre></li>
 +<li><pre typeof="mw:Extension/pre" about="#mwt4" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"bar"}}'>bar</pre></li>
 +<li>zar</li></ul>
  !! end
  
 +# FIXME: Might benefit from a html/parsoid since this has a template
  !! test
  List items from template
  !! wikitext
  
  {{inner list}}
 -* item 2
 +*item 2
  
 -* item 0
 +*item 0
  {{inner list}}
 -* item 2
 +*item 2
  
 -* item 0
 -* notSOL{{inner list}}
 -* item 2
 +*item 0
 +*notSOL{{inner list}}
 +*item 2
  !! html
 -<ul><li> item 1</li>
 -<li> item 2</li></ul>
 -<ul><li> item 0</li>
 -<li> item 1</li>
 -<li> item 2</li></ul>
 -<ul><li> item 0</li>
 -<li> notSOL</li>
 -<li> item 1</li>
 -<li> item 2</li></ul>
 +<ul><li>item 1</li>
 +<li>item 2</li></ul>
 +<ul><li>item 0</li>
 +<li>item 1</li>
 +<li>item 2</li></ul>
 +<ul><li>item 0</li>
 +<li>notSOL</li>
 +<li>item 1</li>
 +<li>item 2</li></ul>
  
  !! end
  
  !! test
  List interrupted by empty line or heading
  !! wikitext
 -* foo
 +*foo
  
 -** bar
 -== A heading ==
 -* Another list item
 +**bar
 +==A heading==
 +*Another list item
  !! html
 -<ul><li> foo</li></ul>
 -<ul><li><ul><li> bar</li></ul></li></ul>
 +<ul><li>foo</li></ul>
 +<ul><li><ul><li>bar</li></ul></li></ul>
  <h2><span class="mw-headline" id="A_heading">A heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 -<ul><li> Another list item</li></ul>
 +<ul><li>Another list item</li></ul>
  
  !!end
  
 -!!test
 +!! test
  Multiple list tags generated by templates
  !! wikitext
  {{echo|<li>}}a
  </li>
  </li>
  
 +
  !! html+tidy
  <li>a
  </li><li>b
  </li><li>c
  </li>
 -!!end
 +!! html/parsoid
 +<li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"a"]}'>a</li>
 +<li about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"b"]}'>b</li>
 +<li about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>"}},"i":0}},"c"]}'>c</li>
 +!! end
  
 -!!test
 -Single-comment whitespace lines dont break lists, and neither do multi-comment whitespace lines
 +!! test
 +Multiple newlines in between HTML list items don't induce paragraph wrapping
  !! wikitext
 -*a
 -<!--This line will NOT split the list-->
 -*b
 - <!--This line will NOT split the list either-->
 -*c
 - <!--foo--> <!----> <!--This line NOT split the list either--> 
 -*d
 -!! html
 -<ul><li>a</li>
 -<li>b</li>
 -<li>c</li>
 -<li>d</li></ul>
 +<ul>
 +<li>hi</li>
  
 -!!end
  
 -!!test
 -Replacing whitespace with tabs still doesn't break the list (gerrit 78327)
 -!! wikitext
 -*a
 -<!--This line will NOT split the list-->      
 -*b
 -      <!--This line will NOT split the list either-->         
 -*c
 +
 +
 +<li>ho</li>
 +</ul>
 +
 +<dl>
 +<dt>hi</dt>
 +<dd>ho<div>123</div>
 +</dd>
 +
 +
 +</dl>
 +!! html/php+tidy
 +<ul>
 +<li>hi</li>
 +
 +
 +
 +
 +<li>ho</li>
 +</ul>
 +<dl>
 +<dt>hi</dt>
 +<dd>ho<div>123</div>
 +</dd>
 +
 +
 +</dl>
 +!! end
 +
 +!!test
 +Single-comment whitespace lines dont break lists, and neither do multi-comment whitespace lines
 +!! wikitext
 +*a
 +<!--This line will NOT split the list-->
 +*b
 + <!--This line will NOT split the list either-->
 +*c
 + <!--foo--> <!----> <!--This line NOT split the list either--> 
 +*d
 +!! html
 +<ul><li>a</li>
 +<li>b</li>
 +<li>c</li>
 +<li>d</li></ul>
 +
 +!!end
 +
 +!!test
 +Replacing whitespace with tabs still doesn't break the list (gerrit 78327)
 +!! wikitext
 +*a
 +<!--This line will NOT split the list-->      
 +*b
 +      <!--This line will NOT split the list either-->         
 +*c
        <!--foo--> <!---->      <!--This line NOT split the list
          either-->      
  *d
@@@ -10189,29 -9821,29 +10189,29 @@@ Test the li-hack (a hack from Tidy days
  !!options
  parsoid=wt2html,wt2wt
  !! wikitext
 -* foo
 -* <li>li-hack
 -* {{echo|<li>templated li-hack}}
 -* <!--foo--> <li> unsupported li-hack with preceding comments
 +*foo
 +*<li>li-hack
 +*{{echo|<li>templated li-hack}}
 +*<!--foo--><li> unsupported li-hack with preceding comments
  
  <ul>
  <li><li>not a li-hack
  </li>
  </ul>
  !! html+tidy
 -<ul><li> foo</li>
 -<li class="mw-empty-elt"> </li><li>li-hack</li>
 -<li class="mw-empty-elt"> </li><li>templated li-hack</li>
 -<li class="mw-empty-elt">  </li><li> unsupported li-hack with preceding comments</li></ul>
 +<ul><li>foo</li>
 +<li class="mw-empty-elt"></li><li>li-hack</li>
 +<li class="mw-empty-elt"></li><li>templated li-hack</li>
 +<li class="mw-empty-elt"></li><li> unsupported li-hack with preceding comments</li></ul>
  <ul>
  <li class="mw-empty-elt"></li><li>not a li-hack
  </li>
  </ul>
  !! html/parsoid
  <ul><li> foo</li>
 -<li data-parsoid='{"stx":"html","autoInsertedEnd":true,"liHackSrc":"* "}'>li-hack</li>
 -<li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,,"pi":[[{"k":"1"}]]}' data-mw='{"parts":["* ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>templated li-hack"}},"i":0}}]}'>templated li-hack</li>
 -<li data-parsoid='{"autoInsertedEnd":true}'> <!--foo--> </li><li data-parsoid='{"stx":"html","autoInsertedEnd":true}'> unsupported li-hack with preceding comments</li></ul>
 +<li data-parsoid='{"stx":"html","autoInsertedEnd":true,"liHackSrc":"*"}'>li-hack</li>
 +<li about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,,"pi":[[{"k":"1"}]]}' data-mw='{"parts":["*",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;li>templated li-hack"}},"i":0}}]}'>templated li-hack</li>
 +<li data-parsoid='{"autoInsertedEnd":true}'><!--foo--></li><li data-parsoid='{"stx":"html","autoInsertedEnd":true}'>unsupported li-hack with preceding comments</li></ul>
  
  <ul data-parsoid='{"stx":"html"}'>
  <li class="mw-empty-elt" data-parsoid='{"stx":"html","autoInsertedEnd":true}'></li><li data-parsoid='{"stx":"html"}'>not a li-hack
  
  !! test
  Parsoid: Make sure nested lists are serialized on their own line even if HTML contains no newlines
 -!! options
 -parsoid
  !! wikitext
 -# foo
 -## bar
 -* foo
 -** bar
 -: foo
 -:: bar
 -!! html
 +#foo
 +##bar
 +
 +*foo
 +**bar
 +
 +:foo
 +::bar
 +!! html/php+tidy
 +<ol><li>foo
 +<ol><li>bar</li></ol></li></ol>
 +<ul><li>foo
 +<ul><li>bar</li></ul></li></ul>
 +<dl><dd>foo
 +<dl><dd>bar</dd></dl></dd></dl>
 +!! html/parsoid
  <ol>
 -<li> foo<ol>
 -<li> bar</li>
 +<li>foo<ol>
 +<li>bar</li>
  </ol></li>
  </ol><ul>
 -<li> foo<ul>
 -<li> bar</li>
 +<li>foo<ul>
 +<li>bar</li>
  </ul></li>
  </ul><dl>
 -<dd> foo<dl>
 -<dd> bar</dd>
 +<dd>foo<dl>
 +<dd>bar</dd>
  </dl></dd>
  </dl>
  !! end
  !! test
  Parsoid: Test of whitespace serialization with Templated bullets
  !! options
 -parsoid
 +parsoid=wt2html
  !! wikitext
  * {{bullet}}
  !! html/parsoid
@@@ -10283,7 -9908,7 +10283,7 @@@ Unbalanced closing block tags break a l
  <div>
  <ul><li>a</li></ul></div><div>
  <li>b</li></div>
 -!! html+parsoid
 +!! html/parsoid
  <div><ul>
  <li>a</li>
  </ul></div>
  
  !! test
  Unbalanced closing non-block tags don't break a list
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  <span>
  *a</span><span>
  <ul><li>a<span></span></li>
  <li>b</li></ul>
  !! html/parsoid
 -<span>
 -<ul>
 -<li>a<span></span></li>
 -<li>b</li>
 -</ul>
 -</span>
 +<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'></span></p>
 +<ul><li>a<span data-parsoid='{"stx":"html","autoInsertedEnd":true}'></span></li>
 +<li>b</li></ul>
  !! end
  
  # Parsoid does some post-dom-building cleanup
@@@ -10318,35 -9944,46 +10318,35 @@@ Unclosed formatting tags that straddle 
  !! options
  parsoid=wt2html,wt2wt,html2html
  !! wikitext
 -# <s> a
 -# b </s>
 +#<s> a
 +#b </s>
  !! html/php+tidy
 -<ol><li> <s> a</s></li><s>
 -</s><li><s> b </s></li></ol>
 +<ol><li><s> a</s></li><s>
 +</s><li><s>b </s></li></ol>
  !! html/parsoid
 -<ol><li> <s> a</s><s></s></li>
 -<li><s> b </s></li></ol>
 +<ol><li><s> a</s></li>
 +<li><s>b </s></li></ol>
  !! end
  
  # Output is ugly because of all the misnested tag fixups.
 -# Remex is wrapping p-tags around empty elements.
 -# Parsoid has special-case handling of this pattern of
 -# wrapping lists in formatting tags.
 -# FIXME: Should we remove this code from Parsoid? Or add
 -# special support in Remex? If the latter, maybe just wait
 -# for Parsoid to become the default parser.
 -# See T70395.
 -!!test
 +!! test
  1. List embedded in a formatting tag
  !! wikitext
  <small>
 -* foo
 +*foo
  </small>
  !! html/php+tidy
  <p><small>
 -</small></p><small><ul><li> foo</li></ul></small><small></small><p><small></small>
 +</small></p><small><ul><li>foo</li></ul></small><small></small><p><small></small>
  </p>
  !! html/parsoid
 -<small>
 -<ul>
 -<li> foo</li>
 -</ul>
 -</small>
 -!!end
 +<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
 +<ul><li data-parsoid='{}'>foo</li></ul></small>
 +<p><small data-parsoid='{"stx":"html","autoInsertedStart":true}'></small></p>
 +!! end
  
 -# Output is ugly because of all the misnested tag fixups
 -# Remex is wrapping p-tags around empty elements.
 -# Parsoid has code that strips useless p-tags.
 -!!test
 +# Output is ugly because of all the misnested tag fixups.
 +!! test
  2. List embedded in a formatting tag in a misnested way
  !! wikitext
  <small>
  </small></p><small></small><ul><small><li>a</li>
  </small><li><small>b</small></li></ul>
  !! html/parsoid
 -<small></small>
 -<ul><small>
 -<li>a</li>
 -</small>
 -<li><small>b</small></li>
 -</ul>
 -!!end
 +<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p>
 +<ul><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'><li>a</li></small>
 +<li><small data-parsoid='{"stx":"html","autoInsertedStart":true}'>b</small></li></ul>
 +!! end
  
 +# Output is ugly because of all the misnested tag fixups.
  !! test
 -Table with missing opening <tr> tag
 -!! options
 -parsoid=wt2html,wt2wt
 +3. List embedded in a formatting tag in a misnested way
  !! wikitext
 -<table>
 -<td>foo</td>
 -</tr>
 -</table>
 -!! html+tidy
 -<table>
 -<tbody><tr><td>foo</td>
 -</tr>
 -</tbody></table>
 +<small>
 +
 +** 123</small>
 +!! html/php+tidy
 +<p><small>
 +</small></p><small></small><ul><small></small><li><small></small><ul><small></small><li><small>123</small></li></ul></li></ul>
 +!! html/parsoid
 +<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p>
 +
 +<ul><li><ul><li data-parsoid='{}'><small data-parsoid='{"stx":"html","autoInsertedStart":true}'> 123</small></li></ul></li></ul>
  !! end
  
  ###
@@@ -10516,35 -10156,35 +10516,35 @@@ Magic Word: {{CURRENTTIMESTAMP}
  !! test
  Magic Words LOCAL (UTC)
  !! wikitext
 -* {{LOCALMONTH}}
 -* {{LOCALMONTH1}}
 -* {{LOCALMONTHNAME}}
 -* {{LOCALMONTHNAMEGEN}}
 -* {{LOCALMONTHABBREV}}
 -* {{LOCALDAY}}
 -* {{LOCALDAY2}}
 -* {{LOCALDAYNAME}}
 -* {{LOCALYEAR}}
 -* {{LOCALTIME}}
 -* {{LOCALHOUR}}
 -* {{LOCALWEEK}}
 -* {{LOCALDOW}}
 -* {{LOCALTIMESTAMP}}
 -!! html
 -<ul><li> 01</li>
 -<li> 1</li>
 -<li> January</li>
 -<li> January</li>
 -<li> Jan</li>
 -<li> 1</li>
 -<li> 01</li>
 -<li> Thursday</li>
 -<li> 1970</li>
 -<li> 00:02</li>
 -<li> 00</li>
 -<li> 1</li>
 -<li> 4</li>
 -<li> 19700101000203</li></ul>
 +*{{LOCALMONTH}}
 +*{{LOCALMONTH1}}
 +*{{LOCALMONTHNAME}}
 +*{{LOCALMONTHNAMEGEN}}
 +*{{LOCALMONTHABBREV}}
 +*{{LOCALDAY}}
 +*{{LOCALDAY2}}
 +*{{LOCALDAYNAME}}
 +*{{LOCALYEAR}}
 +*{{LOCALTIME}}
 +*{{LOCALHOUR}}
 +*{{LOCALWEEK}}
 +*{{LOCALDOW}}
 +*{{LOCALTIMESTAMP}}
 +!! html
 +<ul><li>01</li>
 +<li>1</li>
 +<li>January</li>
 +<li>January</li>
 +<li>Jan</li>
 +<li>1</li>
 +<li>01</li>
 +<li>Thursday</li>
 +<li>1970</li>
 +<li>00:02</li>
 +<li>00</li>
 +<li>1</li>
 +<li>4</li>
 +<li>19700101000203</li></ul>
  
  !! end
  
  # From plwiki:PLOS_ONE
  !! test
  Parsoid: Page property magic word with magic word contents
 +!! options
 +showtitle
 +!! config
 +wgAllowDisplayTitle=true
 +wgRestrictDisplayTitle=false
  !! wikitext
  {{DISPLAYTITLE:''{{PAGENAME}}''}}
 +!! html/php+tidy
 +<i>Parser test</i>
 +
  !! html/parsoid
 -<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Main Page&lt;/span>&lt;/i>"}]]}'/>
 +<meta property="mw:PageProp/displaytitle" content="Parser test" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Parser test&lt;/span>&lt;/i>"}]]}'/>
  !! end
  
  # NOTE: mw:ExpandedAttrs is not the best typeof here. mw:Transclusion is better.
@@@ -11239,7 -10871,7 +11239,7 @@@ RFC 82
  <p><a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc822">RFC 822</a>
  </p>
  !! html/parsoid
 -<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC 822</a></p>
 +<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC 822</a></p>
  !! end
  
  !! test
@@@ -11250,7 -10882,7 +11250,7 @@@ This is RFC 822 but thisRFC 822 is not 
  <p>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc822">RFC 822</a> but thisRFC 822 is not RFC 822linked.
  </p>
  !! html/parsoid
 -<p>This is <a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC 822</a> but thisRFC 822 is not RFC 822linked.</p>
 +<p>This is <a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC 822</a> but thisRFC 822 is not RFC 822linked.</p>
  !! end
  
  !! test
  822
  </p>
  !! html/parsoid
 -<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external text">RFC <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 822</a>
 +<p><a href="https://tools.ietf.org/html/rfc822" rel="mw:ExtLink" class="external mw-magiclink">RFC <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 822</a>
  RFC
  822</p>
  !! end
@@@ -11323,7 -10955,7 +11323,7 @@@ PMID 123
  <p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a>
  </p>
  !! html/parsoid
 -<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a></p>
 +<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a></p>
  !! end
  
  !! test
@@@ -11334,7 -10966,7 +11334,7 @@@ This is PMID 1234 but thisPMID 1234 is 
  <p>This is <a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.
  </p>
  !! html/parsoid
 -<p>This is <a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.</p>
 +<p>This is <a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a> but thisPMID 1234 is not PMID 1234linked.</p>
  !! end
  
  !! test
  1234
  </p>
  !! html/parsoid
 -<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 1234</a>
 +<p><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID <span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#0160;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#xA0;","srcContent":" "}'> </span><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#Xa0;","srcContent":" "}'> </span> 1234</a>
  PMID
  1234</p>
  !! end
@@@ -11618,11 -11250,11 +11618,11 @@@ Templates with templated nam
  !! html
  <p>foo
  </p>
 -<ul><li> item 1</li></ul>
 +<ul><li>item 1</li></ul>
  
  !! html/parsoid
  <p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"{{echo|echo}}","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}}]}'>foo</p>
 -<ul about="#mwt4" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"{{echo|inner list}} ","href":"./Template:Inner_list"},"params":{},"i":0}}]}'><li> item 1</li></ul>
 +<ul about="#mwt4" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"{{echo|inner list}} ","href":"./Template:Inner_list"},"params":{},"i":0}}]}'><li>item 1</li></ul>
  !! end
  
  ## Regression test; the output here isn't really that interesting.
@@@ -11706,28 -11338,28 +11706,28 @@@ T2553: link with two variables in a pip
  Abort table cell attribute parsing on wikilink
  !! wikitext
  {|
 -| testing [[one|two]] | three || four
 -| testing one two | three || four
 -| testing="[[one|two]]" | three || four
 +|testing [[one|two]] |three||four
 +|testing one two |three||four
 +|testing="[[one|two]]" |three||four
  |}
  !! html/php
  <table>
  <tr>
 -<td> testing <a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a> | three </td>
 -<td> four
 +<td>testing <a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a> |three</td>
 +<td>four
  </td>
 -<td> three </td>
 -<td> four
 +<td>three</td>
 +<td>four
  </td>
 -<td> testing="<a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a>" | three </td>
 -<td> four
 +<td>testing="<a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a>" |three</td>
 +<td>four
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'> testing <a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a> | three </td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'> four</td>
 -<td data-parsoid='{"a":{"testing":null,"one":null,"two":null},"sa":{"testing":"","one":"","two":""},"autoInsertedEnd":true}'> three </td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'> four</td>
 -<td> testing="<a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a>" | three </td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'> four</td></tr>
 +<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'>testing <a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a> |three</td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'>four</td>
 +<td data-parsoid='{"a":{"testing":null,"one":null,"two":null},"sa":{"testing":"","one":"","two":""},"autoInsertedEnd":true}'>three</td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'>four</td>
 +<td>testing="<a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"piped","a":{"href":"./One"},"sa":{"href":"one"}}'>two</a>" |three</td><td data-parsoid='{"stx":"row","autoInsertedEnd":true}'>four</td></tr>
  </tbody></table>
  !! end
  
  Don't abort table cell attribute parsing if wikilink is found in template arg
  !! wikitext
  {|
 -| Test {{#tag:ref|One two "[[three]]" four}}
 +|Test {{#tag:ref|One two "[[three]]" four}}
  |}
  !! html/parsoid
  <table>
 -<tbody><tr><td> Test <ref about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:ref","function":"tag"},"params":{"1":{"wt":"One two \"[[three]]\" four"}},"i":0}}]}'>One two "<a rel="mw:WikiLink" href="./Three" title="Three">three</a>" four</ref></td></tr>
 +<tbody><tr><td>Test <ref about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"#tag:ref","function":"tag"},"params":{"1":{"wt":"One two \"[[three]]\" four"}},"i":0}}]}'>One two "<a rel="mw:WikiLink" href="./Three" title="Three">three</a>" four</ref></td></tr>
  </tbody></table>
  !! end
  
@@@ -11834,17 -11466,6 +11834,17 @@@ Template from main namespac
  </p>
  !! end
  
 +!! test
 +Template from non-includable namespace
 +!! options
 +wgNonincludableNamespaces=10
 +!! wikitext
 +{{echo|uh oh!}}
 +!! html
 +<p><a href="/wiki/Template:Echo" title="Template:Echo">Template:Echo</a>
 +</p>
 +!! end
 +
  !! article
  Template:table
  !! text
@@@ -11864,12 -11485,12 +11864,12 @@@ foo {{table}
  </p>
  <table>
  <tr>
 -<td> 1 </td>
 -<td> 2
 +<td>1</td>
 +<td>2
  </td></tr>
  <tr>
 -<td> 3 </td>
 -<td> 4
 +<td>3</td>
 +<td>4
  </td></tr></table>
  
  !! end
  </p>
  <table>
  <tr>
 -<td> 1 </td>
 -<td> 2
 +<td>1</td>
 +<td>2
  </td></tr>
  <tr>
 -<td> 3 </td>
 -<td> 4
 +<td>3</td>
 +<td>4
  </td></tr></table>
  
  !! end
@@@ -12195,7 -11816,7 +12195,7 @@@ Un-closed <includeonly
  <includeonly>
  !! html/php
  !! html/parsoid
 -<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>"}'/>
 +<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>"}' data-mw='{"src":"&lt;includeonly>"}'/>
  !! end
  
  ## We used to, but no longer wt2wt this test since the default serializer
@@@ -12207,44 -11828,32 +12207,44 @@@ Includes and comments at SO
  !! options
  parsoid=wt2html,html2html
  !! wikitext
 -<!-- comment --><noinclude><!-- comment --></noinclude><!-- comment -->== hu ==
 +<!-- comment --><noinclude><!-- comment --></noinclude><!-- comment -->==hu==
  
  <noinclude>
  some
 -</noinclude>* stuff
 +</noinclude>*stuff
 +*here
 +
 +<noinclude>
 +some</noinclude>* stuff
  * here
  
 -<includeonly>can have stuff</includeonly>=== here ===
 +<includeonly>can have stuff</includeonly>===here===
  
  !! html/php
  <h2><span class="mw-headline" id="hu">hu</span></h2>
  <p>some
  </p>
 -<ul><li> stuff</li>
 -<li> here</li></ul>
 +<ul><li>stuff</li>
 +<li>here</li></ul>
 +<p><br />
 +some* stuff
 +</p>
 +<ul><li>here</li></ul>
  <h3><span class="mw-headline" id="here">here</span></h3>
  
  !! html/parsoid
 -<!-- comment --><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/><!-- comment --><meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/><!-- comment --><h2 id="hu"> hu </h2>
 +<!-- comment --><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/><!-- comment --><meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/><!-- comment --><h2 id="hu">hu</h2>
  
  <meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>
  <p>some</p>
 -<meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/><ul><li> stuff</li>
 -<li> here</li></ul>
 +<meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/><ul><li>stuff</li>
 +<li>here</li></ul>
 +
 +<meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>
 +<p>some<meta typeof="mw:Includes/NoInclude/End" data-parsoid='{"src":"&lt;/noinclude>"}'/>* stuff</p>
 +<ul><li>here</li></ul>
  
 -<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>can have stuff&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><h3 id="here"> here </h3>
 +<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>can have stuff&lt;/includeonly>"}' data-mw='{"src":"&lt;includeonly>can have stuff&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><h3 id="here">here</h3>
  
  !! end
  
  <table></table>
  
  b}}
 -!! html
 +!! html/php+tidy
 +<p>ab</p><table></table><p>cd
 +</p><p>ab
 +</p>
 +<table></table>
 +<p>cd
 +</p><p>a
 +</p>
 +<table></table>
 +<p>b
 +</p>
 +!! html/parsoid
  <p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["a",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b&lt;table>&lt;/table>c"}},"i":0}},"d"]}' data-parsoid='{"pi":[[{"k":"1"}]]}'>ab</p><table about="#mwt1" data-parsoid='{"stx":"html"}'></table><p about="#mwt1">cd</p>
  
  <p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["a",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b\n&lt;table>&lt;/table>\nc"}},"i":0}},"d"]}' data-parsoid='{"pi":[[{"k":"1"}]]}'>ab</p><span about="#mwt2">
  
  !! test
  Parsoid: Merge double tds (T52603)
 -!! options
 -parsoid
  !! wikitext
  {|
  |{{echo|{{!}} foo}}
  |}
 -!! html
 +!! html/php+tidy
 +<table>
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +!! html/parsoid
  <table><tbody>
  <tr><td about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":0}}]}'> foo</td></tr>
  </tbody></table>
  
  !! test
  Parsoid: Merge double tds in nested transclusion content (T52603)
 -!! options
 -parsoid
  !! wikitext
  {{echo|<div>}}
  {|
  |{{echo|{{!}} foo}}
  |}
  {{echo|</div>}}
 -!! html
 +!! html/php+tidy
 +<div>
 +<table>
 +<tbody><tr>
 +<td>foo
 +</td></tr></tbody></table>
 +</div>
 +!! html/parsoid
  <div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<div>"}},"i":0}},"\n{|\n|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":1}},"\n|}\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"</div>"}},"i":2}}]}'>
  <table><tbody>
  <tr><td data-mw='{"parts":["|"]}'> foo</td></tr>
@@@ -12482,10 -12072,10 +12482,10 @@@ Preprocessor precedence 5: tplarg take
  !! wikitext
  {{Precedence5|Bullet}}
  !! html/php
 -<ul><li> Bar</li></ul>
 +<ul><li>Bar</li></ul>
  
  !! html/parsoid
 -<ul typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Precedence5","href":"./Template:Precedence5"},"params":{"1":{"wt":"Bullet"}},"i":0}}]}'><li> Bar</li></ul>
 +<ul typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Precedence5","href":"./Template:Precedence5"},"params":{"1":{"wt":"Bullet"}},"i":0}}]}'><li>Bar</li></ul>
  !! end
  
  !! test
@@@ -12575,14 -12165,14 +12575,14 @@@ Preprocessor precedence 9: groups of br
  {{Preprocessor precedence 9|Four|Bullet|1|2}}
  !! html/php
  <dl><dt>4</dt>
 -<dd> {Four}</dd>
 +<dd>{Four}</dd>
  <dt>5</dt>
 -<dd> </dd></dl>
 -<ul><li> Bar</li></ul>
 +<dd></dd></dl>
 +<ul><li>Bar</li></ul>
  <dl><dt>6</dt>
 -<dd> Four</dd>
 +<dd>Four</dd>
  <dt>7</dt>
 -<dd> {Bullet}</dd></dl>
 +<dd>{Bullet}</dd></dl>
  
  !! html/parsoid
  <dl about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Preprocessor precedence 9","href":"./Template:Preprocessor_precedence_9"},"params":{"1":{"wt":"Four"},"2":{"wt":"Bullet"},"3":{"wt":"1"},"4":{"wt":"2"}},"i":0}}]}'>
@@@ -12620,21 -12210,21 +12620,21 @@@ language=z
  {{Preprocessor precedence 10|Three|raw2|Bullet|1|2}}
  !! html/php
  <dl><dt>1</dt>
 -<dd> raw</dd>
 +<dd>raw</dd>
  <dt>2</dt>
 -<dd> -</dd></dl>
 -<ul><li> Bar-</li></ul>
 +<dd>-</dd></dl>
 +<ul><li>Bar-</li></ul>
  <dl><dt>3</dt>
 -<dd> -Three-</dd>
 +<dd>-Three-</dd>
  <dt>4</dt>
 -<dd> raw2</dd>
 +<dd>raw2</dd>
  <dt>5</dt>
 -<dd> -</dd></dl>
 -<ul><li> Bar-</li></ul>
 +<dd>-</dd></dl>
 +<ul><li>Bar-</li></ul>
  <dl><dt>6</dt>
 -<dd> -Three-</dd>
 +<dd>-Three-</dd>
  <dt>7</dt>
 -<dd> raw2</dd></dl>
 +<dd>raw2</dd></dl>
  
  !! html/parsoid
  <dl about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"Preprocessor precedence 10","href":"./Template:Preprocessor_precedence_10"},"params":{"1":{"wt":"Three"},"2":{"wt":"raw2"},"3":{"wt":"Bullet"},"4":{"wt":"1"},"5":{"wt":"2"}},"i":0}}]}'>
@@@ -12688,14 -12278,14 +12688,14 @@@ Preprocessor precedence 12: broken lang
  parsoid=wt2html
  !! wikitext
  This form breaks the template, which is unfortunate:
 -* {{echo|foo-{bar}bat}}
 +*{{echo|foo-{bar}bat}}
  
  But if the broken language converter markup is inside an extension
  tag, nothing bad happens:
 -* <nowiki>foo-{bar}bat</nowiki>
 -* {{echo|<nowiki>foo-{bar}bat</nowiki>}}
 -* <pre>foo-{bar}bat</pre>
 -* {{echo|<pre>foo-{bar}bat</pre>}}
 +*<nowiki>foo-{bar}bat</nowiki>
 +*{{echo|<nowiki>foo-{bar}bat</nowiki>}}
 +*<pre>foo-{bar}bat</pre>
 +*{{echo|<pre>foo-{bar}bat</pre>}}
  
  <tag>foo-{bar}bat</tag>
  {{echo|<tag>foo-{bar}bat</tag>}}
  !! html/php+tidy
  <p>This form breaks the template, which is unfortunate:
  </p>
 -<ul><li> {{echo|foo-{bar}bat}}</li></ul>
 +<ul><li>{{echo|foo-{bar}bat}}</li></ul>
  <p>But if the broken language converter markup is inside an extension
  tag, nothing bad happens:
  </p>
 -<ul><li> foo-&#123;bar}bat</li>
 -<li> foo-&#123;bar}bat</li>
 -<li> <pre>foo-{bar}bat</pre></li>
 -<li> <pre>foo-{bar}bat</pre></li></ul>
 +<ul><li>foo-&#123;bar}bat</li>
 +<li>foo-&#123;bar}bat</li>
 +<li><pre>foo-{bar}bat</pre></li>
 +<li><pre>foo-{bar}bat</pre></li></ul>
  <pre>'foo-{bar}bat'
  array (
  )
@@@ -12729,7 -12319,7 +12729,7 @@@ array 
  <li><span typeof="mw:Nowiki">foo-{bar}bat</span></li>
  <li><span typeof="mw:Transclusion mw:Nowiki" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;nowiki>foo-{bar}bat&lt;/nowiki>"}},"i":0}}]}'>foo-{bar}bat</span></li>
  <li><pre typeof="mw:Extension/pre" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'>foo-{bar}bat</pre></li>
 -<li><pre typeof="mw:Transclusion mw:Extension/pre" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
 +<li><pre typeof="mw:Extension/pre mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
  </ul>
  <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'></pre> <pre typeof="mw:Extension/tag mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;tag>foo-{bar}bat&lt;/tag>"}},"i":0}}]}'></pre>
  !! end
@@@ -12739,13 -12329,13 +12739,13 @@@ Preprocessor precedence 13: broken lang
  !! options
  parsoid=wt2html
  !! wikitext
 -* [http://example.com/-{foo Example in URL]
 -* [http://example.com Example in -{link} description]
 -* {{echo|[http://example.com/-{foo Breaks template, however]}}
 +*[http://example.com/-{foo Example in URL]
 +*[http://example.com Example in -{link} description]
 +*{{echo|[http://example.com/-{foo Breaks template, however]}}
  !! html/php+tidy
 -<ul><li> <a rel="nofollow" class="external text" href="http://example.com/-{foo">Example in URL</a></li>
 -<li> <a rel="nofollow" class="external text" href="http://example.com">Example in -{link} description</a></li>
 -<li> {{echo|<a rel="nofollow" class="external text" href="http://example.com/-{foo">Breaks template, however</a>}}</li></ul>
 +<ul><li><a rel="nofollow" class="external text" href="http://example.com/-{foo">Example in URL</a></li>
 +<li><a rel="nofollow" class="external text" href="http://example.com">Example in -{link} description</a></li>
 +<li>{{echo|<a rel="nofollow" class="external text" href="http://example.com/-{foo">Breaks template, however</a>}}</li></ul>
  !! html/parsoid
  <ul>
  <li><a rel="mw:ExtLink" class="external text" href="http://example.com/-{foo">Example in URL</a></li>
  !! test
  Preprocessor precedence 14: broken language converter in comment
  !! wikitext
 -* <!--{{foo}}--> ...should be ok
 -* <!---{{foo}}--> ...extra dashes
 -* {{echo|foo<!-- -{bar} -->bat}} ...should be ok
 +*<!--{{foo}}-->...should be ok
 +*<!---{{foo}}-->...extra dashes
 +*{{echo|foo<!-- -{bar} -->bat}}...should be ok
  !! html/php+tidy
 -<ul><li>  ...should be ok</li>
 -<li>  ...extra dashes</li>
 -<li> foobat ...should be ok</li></ul>
 +<ul><li>...should be ok</li>
 +<li>...extra dashes</li>
 +<li>foobat...should be ok</li></ul>
  !! html/parsoid
  <ul>
 -<li><!--{{foo}}--> ...should be ok</li>
 -<li><!--&#x2D;{{foo}}--> ...extra dashes</li>
 -<li><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;!-- -{bar} -->bat"}},"i":0}}]}'>foo</span><span about="#mwt1"><!-- &#x2D;{bar} --></span><span about="#mwt1">bat</span> ...should be ok</li>
 +<li><!--{{foo}}-->...should be ok</li>
 +<li><!--&#x2D;{{foo}}-->...extra dashes</li>
 +<li><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;!-- -{bar} -->bat"}},"i":0}}]}'>foo</span><span about="#mwt1"><!-- &#x2D;{bar} --></span><span about="#mwt1">bat</span>...should be ok</li>
  </ul>
  !! end
  
@@@ -12854,35 -12444,6 +12854,35 @@@ parsoid=wt2htm
  <p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi {{}}"}},"i":0}}]}'>hi {{}}</p>
  !! end
  
 +# Ensure we're using a language without variants for this test; even
 +# if $wgUsePigLatinVariant is true.  We've picked `de` arbitrarily.
 +!! test
 +Preprocessor precedence 18: another rightmost wins scenario
 +!! options
 +parsoid=wt2html
 +language=de
 +!! wikitext
 +{{ -{{{{1|tplarg}}} }} }-
 +!! html/php
 +<p>{{ -{tplarg }} }-
 +</p>
 +!! html/parsoid
 +<p>{{ -{<span about="#mwt1" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"1"},"params":{"1":{"wt":"tplarg"}},"i":0}}]}'>tplarg</span> }} }-</p>
 +!! end
 +
 +!! test
 +Preprocessor precedence 19: break syntax
 +!! options
 +parsoid=wt2html
 +!! wikitext
 +-{{
 +!! html/php
 +<p>-{{
 +</p>
 +!! html/parsoid
 +<p>-{{</p>
 +!! end
 +
  ###
  ### Token Stream Patcher tests
  ###
@@@ -12918,7 -12479,7 +12918,7 @@@ parsoid=wt2htm
  |c
  |}
  !!html/parsoid
 -<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>a&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}' data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[31,38,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"templatearg\":{\"target\":{\"wt\":\"b\"},\"params\":{},\"i\":0}}]}&#39;>{{{b}}}&lt;/span>"},{"html":""}]]}'>
 +<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>a&lt;/includeonly>"}' data-mw='{"src":"&lt;includeonly>a&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}' data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[31,38,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"templatearg\":{\"target\":{\"wt\":\"b\"},\"params\":{},\"i\":0}}]}&#39;>{{{b}}}&lt;/span>"},{"html":""}]]}'>
  <tbody><tr><td>c</td></tr>
  </tbody></table>
  !!end
@@@ -13056,35 -12617,19 +13056,35 @@@ bar <div>baz</div
  bar </p><div>baz</div>
  !! end
  
 -!!test
 +!! test
  Templates: P-wrapping: 1d. Template preceded by comment-only line
 -!!options
 -parsoid
  !! wikitext
  <!-- foo -->
  {{echo|Bar}}
 -!! html
 +!! html/php+tidy
 +<p>Bar
 +</p>
 +!! html/parsoid
  <!-- foo -->
  
  <p about="#mwt223" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Bar"}},"i":0}}]}'>Bar</p>
  !!end
  
 +!! test
 +Templates: Scopes should not be expanded unnecessarily
 +!! options
 +parsoid=wt2html,wt2wt
 +!! wikitext
 +{{echo|<div>a</div>}}b{{echo|
 +<div>c</div>}}
 +!! html/php+tidy
 +<div>a</div><p>b
 +</p><div>c</div>
 +!! html/parsoid
 +<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>a&lt;/div>"}},"i":0}}]}'>a</div><p>b</p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n&lt;div>c&lt;/div>"}},"i":0}}]}'>
 +</span><div about="#mwt2">c</div>
 +!! end
 +
  !!test
  Templates: Inline Text: 1. Multiple template uses
  !! wikitext
@@@ -13121,20 -12666,16 +13121,20 @@@ Templates: Block Tags: 2. Back-to-back 
  
  !!end
  
 -# This is an edge case relating to paragraph wrapping.
 -!!test
 +## Parsoid drops empty elements in templates.
 +!! test
  Templates: Correctly encapsulate templates producing </p> tag without a corresponding <p> tag
  !! wikitext
  {{echo|a
  b</p>}}
 +!! html/php+tidy
 +<p>a
 +</p><p>
 +b</p><p class="mw-empty-elt"></p>
  !! html/parsoid
 -<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a
 -b</p>
 -!!end
 +<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\nb&lt;/p>"}},"i":0}}]}'>a</p><span about="#mwt1">
 +</span><p about="#mwt1">b</p>
 +!! end
  
  !!test
  Templates: Links: 1. Simple example
@@@ -13315,24 -12856,6 +13315,24 @@@ Templates: Support for templates genera
  </tbody></table>
  !!end
  
 +!! article
 +Template:attribute_from_template
 +!! text
 +class="123"
 +!! endarticle
 +
 +!! test
 +Table cell with attribute before expanded attribute
 +!! wikitext
 +{|
 +| align="center" {{attribute_from_template}} |456
 +|}
 +!! html/parsoid
 +<table>
 +<tbody><tr><td align="center" class="123" about="#mwt2" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"class","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"pi\":[[]],\"dsr\":[20,47,null,null]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"attribute_from_template\",\"href\":\"./Template:Attribute_from_template\"},\"params\":{},\"i\":0}}]}&apos;>class=\"123\"&lt;/span>"},{"html":""}]]}'>456</td></tr>
 +</tbody></table>
 +!! end
 +
  !! test
  1. Entities and nowikis inside templated attributes should be handled correctly
  !! wikitext
  4. Entities and nowikis inside templated attributes should be handled correctly inside templated tables
  !! wikitext
  {|
 -| {{table_attribs_6}} hi
 +|{{table_attribs_6}} hi
  |}
  !! html/php
  <table>
  <tr>
 -<td style="background: red;"> hi
 +<td style="background: red;">hi
  </td></tr></table>
  
  !! html/parsoid
  <table>
 -<tbody><tr><td style="background:  red;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["| ",{"template":{"target":{"wt":"table_attribs_6","href":"./Template:Table_attribs_6"},"params":{},"i":0}}," hi"]}'> hi</td></tr>
 +<tbody><tr><td style="background:  red;" typeof="mw:Transclusion" about="#mwt1" data-parsoid='{"autoInsertedEnd":true,"pi":[[]]}' data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_6","href":"./Template:Table_attribs_6"},"params":{},"i":0}}," hi"]}'> hi</td></tr>
  </tbody></table>
  !! end
  
@@@ -13497,35 -13020,27 +13497,35 @@@ parsoid=wt2html,wt2w
  <table>[[Category:foo1]]<tr><td>foo</td></tr></table>
  <!--Two categories (T52330)-->
  <table>[[Category:bar1]][[Category:bar2]]<tr><td>foo</td></tr></table>
 -!! html
 +!! html/php+tidy
 +<table><tbody><tr><td>foo</td></tr></tbody></table>
 +<table><tbody><tr><td>foo</td></tr></tbody></table>
 +!! html/parsoid
  <link rel="mw:PageProp/Category" href="./Category:Foo1"><table><tbody><tr><td>foo</td></tr></tbody></table>
  <!--Two categories (T52330)-->
  <link rel="mw:PageProp/Category" href="./Category:Bar1"><link rel="mw:PageProp/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table>
  !!end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  Templates: Wiki Tables: 1a. Fostering of entire template content
  !! wikitext
  {|
  {{echo|a}}
  |}
 -!! html
 +!! html/php
  <table>
  a
  <tr><td></td></tr></table>
  
 -!! html+tidy
 +!! html/php+tidy
  
  a
  <table><tbody><tr><td></td></tr></tbody></table>
 +!! html/parsoid
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}},"\n|}"]}'>a</p><table about="#mwt2">
 +
 +</table>
  !! end
  
  !!test
  </table>
  !! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  Templates: Wiki Tables: 2. Fostering of partial template content
  !! wikitext
  {|
  {{echo|a
  <div>b</div>}}
  |}
 -!! html
 +!! html/php
  <table>
  a
  <div>b</div>
  <div>b</div><table>
  <tbody><tr><td></td></tr></tbody></table>
  !! html/parsoid
 -<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</p><div about="#mwt2">b</div><table about="#mwt2">
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"1"}]]}' data-mw='{"parts":["{|\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n&lt;div>b&lt;/div>"}},"i":0}},"\n|}"]}'>a</p><div about="#mwt2">b</div><table about="#mwt2">
  
  
  </table>
@@@ -13643,20 -13157,20 +13643,20 @@@ Templates: Wiki Tables: 6. Templated ta
  ## a <meta> marker tag for <ref> tags and they are expanded
  ## much later. We are verifying that this <meta> tag usage
  ## doesn't prevent foster parenting.
 -!!test
 +!! test
  Templates: Wiki Tables: 7. Fosterable <ref>s should get fostered
 -!!wikitext
 +!! wikitext
  {{PartialTable}}<ref>foo</ref>
  |}
  
  <references />
 -!!html/parsoid
 -<sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><a href="./Main_Page#cite_note-1"><span class="mw-reflink-text">[1]</span></a></sup><table about="#mwt2">
 +!! html/parsoid
 +<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
  <tbody>
  </tbody></table>
  
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 -!!end
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 +!! end
  
  !! test
  Templates: Wiki Tables: 8. Fosterable meta-tags should get fostered
@@@ -13716,9 -13230,7 +13716,9 @@@ Templates: Ugly nesting: 3. Quotes open
  parsoid=wt2html,wt2wt
  !! wikitext
  {{echo_with_div|''a}}{{echo_with_div|b''c''d}}{{echo_with_div|''e}}
 -!! html
 +!! html/php+tidy
 +<div><i>a</i></div><div><i>b</i>c<i>d</i></div><div>e</div>
 +!! html/parsoid
  <div about="#mwt1" typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo_with_div&quot;,&quot;href&quot;:&quot;./Template:Echo_with_div&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;''a&quot;}},&quot;i&quot;:0}}]}"><i>a</i></div>
  <div about="#mwt2" typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo_with_div&quot;,&quot;href&quot;:&quot;./Template:Echo_with_div&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;b''c''d&quot;}},&quot;i&quot;:0}}]}"><i>b</i>c<i>d</i></div>
  <div about="#mwt3" typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo_with_div&quot;,&quot;href&quot;:&quot;./Template:Echo_with_div&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;''e&quot;}},&quot;i&quot;:0}}]}">e</div>
@@@ -13766,8 -13278,8 +13766,8 @@@ Templates: Ugly templates: 5. Template 
  {{echo|<div>foo}}
  {{echo|</table>}}
  !! html/parsoid
 -<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;table>"}},"i":0}},"\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>foo"}},"i":1}},"\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;/table>"}},"i":2}}]}' data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}],[{"k":"1"}],[{"k":"1"}]]}'>foo
 -</div><table about="#mwt1" data-parsoid='{"stx":"html"}'>
 +<div about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","autoInsertedEnd":true,"pi":[[{"k":"1"}],[{"k":"1"}],[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;table>"}},"i":0}},"\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>foo"}},"i":1}},"\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;/table>"}},"i":2}}]}'>foo</div><span about="#mwt1">
 +</span><table about="#mwt1">
  </table>
  !! end
  
@@@ -13827,32 -13339,13 +13827,32 @@@ Parser Functions: 2. Nested use (only o
  </p>
  !!end
  
 -###
 -### Pre-save transform tests
 -###
 +## Note that the templates inside the references are not wrapped
  !! test
 -pre-save transform: subst:
 +Template nested in extension tag in template
  !! options
 -pst
 +title=[[Main Page]]
 +language=zh
 +!! wikitext
 +{{echo|hi<ref>[[ho|{{echo|hi}}]]</ref>}}
 +{{echo|hi<ref>[http://test.com?q={{echo|ho}}]</ref>}}
 +{{echo|hi<ref>-{ho|{{echo|hi}}}-</ref>}}
 +<references />
 +!! html/parsoid
 +<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
 +<span about="#mwt8" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt8" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-2"}}'><a href="./Main_Page#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup>
 +<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>-{ho|{{echo|hi}}}-&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt13" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-3"}}'><a href="./Main_Page#cite_note-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></sup></p>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt17" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho">hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Main_Page#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho"></a></span></li><li about="#cite_note-3" id="cite_note-3"><a href="./Main_Page#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text"><span typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["ho"],"t":"hi"}}'></span></span></li></ol>
 +!! end
 +
 +###
 +### Pre-save transform tests
 +###
 +
 +!! test
 +pre-save transform: subst:
 +!! options
 +pst
  !! wikitext
  {{subst:test}}
  !! html/php
@@@ -14405,20 -13898,11 +14405,20 @@@ a<nowiki / >
  c<nowiki />d
  
  e<nowiki/ >f
 -!! html
 -<p><span typeof="mw:Nowiki">&lt;div&gt;[[foo]]</span></p>
 -<p>ab</p>
 -<p>cd</p>
 -<p>ef</p>
 +!! html/php+tidy
 +<p>&lt;div&gt;[[foo]]
 +</p><p>a&lt;nowiki / &gt;b
 +</p><p>cd
 +</p><p>e&lt;nowiki/ &gt;f
 +</p>
 +!! html/parsoid
 +<p><span typeof="mw:Nowiki">&lt;div>[[foo]]</span></p>
 +
 +<p>a&lt;nowiki / >b</p>
 +
 +<p>c<span typeof="mw:Nowiki"></span>d</p>
 +
 +<p>e&lt;nowiki/ >f</p>
  !! end
  
  !! test
@@@ -14427,10 -13911,7 +14427,10 @@@ Parsoid: Recognize nowiki with odd capi
  parsoid=wt2html
  !! wikitext
  <noWikI ><div>[[foo]]</Nowiki >
 -!! html
 +!! html/php+tidy
 +<p>&lt;div&gt;[[foo]]
 +</p>
 +!! html/parsoid
  <p><span typeof="mw:Nowiki">&lt;div&gt;[[foo]]</span></p>
  !! end
  
@@@ -14804,8 -14285,8 +14804,8 @@@ thumbsize=22
  </p>
  !! html/parsoid
  <p>123<figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline>456</p>
 -<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure><p>456</p>
 -<p>123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
 +<p>123</p><figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure><p>456
 +123</p><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a></figure><p>456</p>
  !! end
  
  !! test
@@@ -15145,368 -14626,6 +15145,368 @@@ Alt image option should handle most kin
  <figure class="mw-default-size" typeof="mw:Image/Thumb mw:ExpandedAttrs" about="#mwt2" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"This is the image caption"},{"ck":"alt","ak":"alt=This is a [[link]] and a {{echo|&apos;&apos;bold template&apos;&apos;}}."}]}' data-mw='{"attribs":[["thumbnail",{"html":"thumb"}],["alt",{"html":"alt=This is a &lt;a rel=\"mw:WikiLink\" href=\"./Link\" title=\"Link\" data-parsoid=&apos;{\"stx\":\"simple\",\"a\":{\"href\":\"./Link\"},\"sa\":{\"href\":\"link\"},\"dsr\":[65,73,2,2]}&apos;>link&lt;/a> and a &lt;i about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&apos;{\"dsr\":[80,106,null,null],\"pi\":[[{\"k\":\"1\"}]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;apos;&amp;apos;bold template&amp;apos;&amp;apos;\"}},\"i\":0}}]}&#39;>bold template&lt;/i>."}]]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img alt="This is a link and a bold template." resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"alt":"This is a link and a bold template.","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=This is a [[link]] and a {{echo|&#39;&#39;bold template&#39;&#39;}}.","resource":"Image:Foobar.jpg"}}'/></a><figcaption>This is the image caption</figcaption></figure>
  !! end
  
 +!! test
 +Ampersand in alt attribute (T206940)
 +!! options
 +parsoid = {
 +  "nativeGallery": true
 +}
 +!! wikitext
 +[[File:Foobar.jpg|alt=&amp;amp;]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|alt=&amp;amp;
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="&amp;amp;" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="&amp;amp;" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="&amp;amp;" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext"></div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Italics markup in alt attribute (T206940)
 +!! wikitext
 +[[File:Foobar.jpg|alt=''x''|caption]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|alt=''x''|caption
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="x" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="x" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&apos;&apos;x&apos;&apos;"},{"ck":"caption","ak":"caption"}]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"x","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=&apos;&apos;x&apos;&apos;","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=&apos;&apos;x&apos;&apos;|caption\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="x" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Nowiki markup in alt attribute (T206940)
 +!! wikitext
 +[[File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|alt=<nowiki>''</nowiki>x<nowiki>''</nowiki>|caption
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="&#39;&#39;x&#39;&#39;" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="&#39;&#39;x&#39;&#39;" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"alt","ak":"alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>"},{"ck":"caption","ak":"caption"}],"dsr":[0,71,null,null]}' data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"&apos;&apos;x&apos;&apos;","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|alt=&lt;nowiki>&apos;&apos;&lt;/nowiki>x&lt;nowiki>&apos;&apos;&lt;/nowiki>|caption\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Nowiki markup in alt attribute (edited html, no data-parsoid) (T206940)
 +!! options
 +parsoid = {
 +  "nativeGallery": true
 +}
 +!! wikitext
 +[[File:Foobar.jpg|alt=<nowiki>''x''</nowiki>|caption]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|alt=<nowiki>''x''</nowiki>|caption
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="&#39;&#39;x&#39;&#39;" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="&#39;&#39;x&#39;&#39;" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img alt="''x''" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Ampersand in link attribute (T206940)
 +!! wikitext
 +[[File:Foobar.jpg|link=Foo &amp; bar]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=Foo &amp; bar
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/Foo_%26_bar" title="Foo &amp; bar"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Foo_%26_bar"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=Foo &amp;amp; bar"}]}'><a href="./Foo_&amp;_bar" data-parsoid='{"a":{"href":"./Foo_&amp;_bar"},"sa":{"href":"link=Foo &amp;amp; bar"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=Foo &amp;amp; bar\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foo_&amp;_bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext"></div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Ampersand in link attribute (edited html, no data-parsoid) (T206940)
 +!! options
 +parsoid = {
 +  "nativeGallery": true
 +}
 +!! wikitext
 +[[File:Foobar.jpg|link=Foo_&_bar]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=Foo_&_bar
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/Foo_%26_bar" title="Foo &amp; bar"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Foo_%26_bar"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="./Foo_&amp;_bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foo_&amp;_bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext"></div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Italics markup in link attribute (T206940)
 +!! wikitext
 +[[Foo''s bar''s]]
 +
 +<!-- Note that "italics" are stripped, even though this is a valid page title -->
 +[[File:Foobar.jpg|link=Foo''s bar''s|caption1]]
 +
 +[[File:Foobar.jpg|link=''Main Page''|caption2]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=Foo''s bar''s|caption1
 +File:Foobar.jpg|link=''Main Page''|caption2
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/Foo%27%27s_bar%27%27s" title="Foo&#39;&#39;s bar&#39;&#39;s">Foo''s bar''s</a>
 +</p><p><a href="/wiki/Foos_bars" title="caption1"><img alt="caption1" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p><p><a href="/wiki/Main_Page" title="caption2"><img alt="caption2" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Foos_bars"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption1
 +</p>
 +                      </div>
 +              </div></li>
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Main_Page"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption2
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><a rel="mw:WikiLink" href="./Foo''s_bar''s" title="Foo''s bar''s">Foo''s bar''s</a></p>
 +
 +<!-- Note that "italics" are stripped, even though this is a valid page title -->
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=Foo&apos;&apos;s bar&apos;&apos;s"},{"ck":"caption","ak":"caption1"}]}' data-mw='{"caption":"caption1"}'><a href="./Foos_bars" data-parsoid='{"a":{"href":"./Foos_bars"},"sa":{"href":"link=Foo&apos;&apos;s bar&apos;&apos;s"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&apos;&apos;Main Page&apos;&apos;"},{"ck":"caption","ak":"caption2"}]}' data-mw='{"caption":"caption2"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=&apos;&apos;Main Page&apos;&apos;"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=Foo&apos;&apos;s bar&apos;&apos;s|caption1\nFile:Foobar.jpg|link=&apos;&apos;Main Page&apos;&apos;|caption2\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foos_bars"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption1</div>
 +</li>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption2</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Nowiki markup in link attribute (T206940)
 +!! wikitext
 +[[File:Foobar.jpg|link=Foo<nowiki>''</nowiki>s_bar<nowiki>''</nowiki>s|caption]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=Foo<nowiki>''</nowiki>s_bar<nowiki>''</nowiki>s|caption
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/Foo%27%27s_bar%27%27s" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Foo%27%27s_bar%27%27s"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=Foo&lt;nowiki>&apos;&apos;&lt;/nowiki>s_bar&lt;nowiki>&apos;&apos;&lt;/nowiki>s"},{"ck":"caption","ak":"caption"}]}' data-mw='{"caption":"caption"}'><a href="./Foo''s_bar''s" data-parsoid='{"a":{"href":"./Foo&apos;&apos;s_bar&apos;&apos;s"},"sa":{"href":"link=Foo&lt;nowiki>&apos;&apos;&lt;/nowiki>s_bar&lt;nowiki>&apos;&apos;&lt;/nowiki>s"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=Foo&lt;nowiki>&apos;&apos;&lt;/nowiki>s_bar&lt;nowiki>&apos;&apos;&lt;/nowiki>s|caption\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foo''s_bar''s"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +Nowiki markup in link attribute (edited html, no data-parsoid) (T206940)
 +!! options
 +parsoid = {
 +  "nativeGallery": true
 +}
 +!! wikitext
 +[[File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption
 +</gallery>
 +!! html/php+tidy
 +<p><a href="/wiki/Foo%27%27s_bar%27%27s" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/Foo%27%27s_bar%27%27s"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +<p>caption
 +</p>
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Foo''s_bar''s"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="./Foo''s_bar''s"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext">caption</div>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +HTML entity prefix in link markup (T209236)
 +!! wikitext
 +[[File:Foobar.jpg|link=https://example.com?foo&params=bar]]
 +
 +<!-- consistency with gallery extension -->
 +<gallery>
 +File:Foobar.jpg|link=https://example.com?foo&params=bar
 +</gallery>
 +!! html/php+tidy
 +<p><a href="https://example.com?foo&amp;params=bar" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 +</p>
 +<ul class="gallery mw-gallery-traditional">
 +              <li class="gallerybox" style="width: 155px"><div style="width: 155px">
 +                      <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="https://example.com?foo&amp;params=bar"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
 +                      <div class="gallerytext">
 +                      </div>
 +              </div></li>
 +</ul>
 +!! html/parsoid
 +<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
 +
 +<!-- consistency with gallery extension -->
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=https://example.com?foo&amp;params=bar\n"}}'>
 +<li class="gallerybox">
 +<div class="thumb"><figure-inline typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
 +<div class="gallerytext"></div>
 +</li>
 +</ul>
 +!! end
 +
  !! test
  Image with table with attributes in caption
  !! options
@@@ -15565,32 -14684,13 +15565,32 @@@ Image with nested tables in captio
  </figcaption></figure>
  !! end
  
 -###################
 -# Conflicting image format options.
 -# First option specified should 'win'.
 -# All three cases in each test should be identical.
 -
  !! test
 -Image with 'frameless' first.
 +Image with heading and horizontal rule in caption
 +!! wikitext
 +[[File:Foobar.jpg|thumb|
 +===Testing===
 +123
 +--------------
 +]]
 +!! html/php
 +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><h3><span class="mw-headline" id="Testing">Testing</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Testing">edit</a><span class="mw-editsection-bracket">]</span></span></h3> 123 <hr /></div></div></div>
 +
 +!! html/parsoid
 +<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"\n=== Testing ===\n123\n--------------\n"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>
 +<h3 id="Testing">Testing</h3>
 +123
 +<hr data-parsoid='{"extra_dashes":10}'/>
 +</figcaption></figure>
 +!! end
 +
 +###################
 +# Conflicting image format options.
 +# First option specified should 'win'.
 +# All three cases in each test should be identical.
 +
 +!! test
 +Image with 'frameless' first.
  !! options
  parsoid=wt2html,wt2wt,html2html
  !! wikitext
@@@ -15876,30 -14976,6 +15876,30 @@@ parsoid=wt2html,wt2wt,html2htm
  <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.svg"><img resource="./File:Foobar.svg" src="//example.com/images/thumb/f/ff/Foobar.svg/220px-Foobar.svg.png" data-file-width="240" data-file-height="180" data-file-type="drawing" height="165" width="220"/></a><figcaption>lang=invalid:language:code</figcaption></figure>
  !! end
  
 +!! test
 +SVG thumbnails in page language
 +!! options
 +language=ru
 +wgMediaInTargetLanguage = true
 +!! wikitext
 +[[File:Foobar.svg]] [[File:Foobar.svg|lang=en]]
 +!! html/php
 +<p><a href="/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/langru-240px-Foobar.svg.png" width="240" height="180" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langru-360px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langru-480px-Foobar.svg.png 2x" /></a> <a href="/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Foobar.svg&amp;lang=en" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/240px-Foobar.svg.png" width="240" height="180" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/480px-Foobar.svg.png 2x" /></a>
 +</p>
 +!! end
 +
 +!! test
 +SVG thumbnails in page language not present in the file
 +!! options
 +language=de
 +wgMediaInTargetLanguage = true
 +!! wikitext
 +[[File:Foobar.svg]] [[File:Foobar.svg|lang=ru]]
 +!! html/php
 +<p><a href="/wiki/Datei:Foobar.svg" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/240px-Foobar.svg.png" width="240" height="180" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/480px-Foobar.svg.png 2x" /></a> <a href="/index.php?title=Datei:Foobar.svg&amp;lang=ru" class="image"><img alt="Foobar.svg" src="http://example.com/images/thumb/f/ff/Foobar.svg/langru-240px-Foobar.svg.png" width="240" height="180" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langru-360px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langru-480px-Foobar.svg.png 2x" /></a>
 +</p>
 +!! end
 +
  !! test
  T3887: A ISBN with a thumbnail
  !! wikitext
@@@ -15919,7 -14995,7 +15919,7 @@@ T3887: A RFC with a thumbnai
  <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
  
  !! html/parsoid
 -<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is <a href="https://tools.ietf.org/html/rfc12354" rel="mw:ExtLink" class="external text">RFC 12354</a></figcaption></figure>
 +<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>This is <a href="https://tools.ietf.org/html/rfc12354" rel="mw:ExtLink" class="external mw-magiclink">RFC 12354</a></figcaption></figure>
  !! end
  
  !! test
@@@ -16080,10 -15156,6 +16080,10 @@@ Image: caption containing leading spac
  <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption> bar</figcaption></figure>
  !!end
  
 +# html/php output not have newlines after table, td, th, etc. because
 +# Linker::makeThumbLink2() replaces the newlines with spaces since
 +# the table is inside a caption.
 +# FIXME: Verify if that circa 2004 fix is still required.
  !! test
  Image: caption containing a table
  !! options
@@@ -16091,21 -15163,21 +16091,21 @@@ parsoid=wt2html,wt2wt,html2htm
  !! wikitext
  [[Image:Foobar.jpg|thumb|200px|This is an example image thumbnail caption with a table
  {|
 -! Foo !! Bar
 +!Foo!!Bar
  |-
 -| Foo1 || Bar1
 +|Foo1||Bar1
  |}
  and some more text.]]
  !! html/php
 -<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is an example image thumbnail caption with a table <table> <tr> <th> Foo </th> <th> Bar </th></tr> <tr> <td> Foo1 </td> <td> Bar1 </td></tr></table> and some more text.</div></div></div>
 +<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>This is an example image thumbnail caption with a table <table> <tr> <th>Foo</th> <th>Bar </th></tr> <tr> <td>Foo1</td> <td>Bar1 </td></tr></table> and some more text.</div></div></div>
  
  !! html/parsoid
  <figure typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption>This is an example image thumbnail caption with a table
  <table>
  <tbody>
 -<tr><th>Foo </th><th>Bar</th></tr>
 +<tr><th>Foo</th><th>Bar</th></tr>
  <tr>
 -<td>Foo1 </td>
 +<td>Foo1</td>
  <td>Bar1</td></tr></tbody></table>and some more text.</figcaption></figure>
  !! end
  
@@@ -16256,7 -15328,8 +16256,7 @@@ Parsoid-specific image handling - simpl
  !! end
  
  !! test
 -Parsoid-specific image handling - simple image with size, middle alignment,
 -non-standard namespace alias
 +Parsoid-specific image handling - simple image with size, middle alignment, non-standard namespace alias
  !! options
  parsoid=wt2wt,wt2html,html2html
  !! wikitext
  !! end
  
  !! test
 -Parsoid-specific image handling - simple image with size and middle alignment
 -(existing content)
 +Parsoid-specific image handling - simple image with size and middle alignment (existing content)
  !! wikitext
  [[File:Foobar.jpg|50px|middle]]
  !! html/parsoid
  !! end
  
  !! test
 -Parsoid-specific image handling - simple image with size and middle alignment
 -and non-standard namespace name
 +Parsoid-specific image handling - simple image with size and middle alignment and non-standard namespace name
  !! options
  parsoid=wt2html,wt2wt,html2html
  !! wikitext
@@@ -16301,46 -15376,41 +16301,46 @@@ Parsoid-specific image handling - simpl
  
  !! test
  Parsoid-specific image handling - thumbnail with halign, valign, and caption
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  [[File:Foobar.jpg|left|baseline|thumb|caption content]]
  !! html/parsoid
 -<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption content</figcaption></figure>
 +<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption content</figcaption></figure>
  !! end
  
  !! test
 -Parsoid-specific image handling - thumbnail with halign, valign, and caption
 -(existing content)
 +Parsoid-specific image handling - thumbnail with halign, valign, and caption (existing content)
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  [[File:Foobar.jpg|thumb|left|baseline|caption content]]
  !! html/parsoid
 -<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption content</figcaption></figure>
 +<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"left","ak":"left"},{"ck":"baseline","ak":"baseline"},{"ck":"caption","ak":"caption content"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption content</figcaption></figure>
  !! end
  
  !! test
  Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  [[Image:Foobar.jpg|right|middle|thumb|50x50px|caption]]
  !! html/parsoid
 -<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption>caption</figcaption></figure>
 +<figure class="mw-halign-right" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50"/></a><figcaption>caption</figcaption></figure>
  !! end
  
  !! test
 -Parsoid-specific image handling - thumbnail with specific size, halign,
 -valign, and caption (existing content)
 +Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption (existing content)
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  [[File:Foobar.jpg|thumb|50x50px|right|middle|caption]]
  !! html/parsoid
 -<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"50x50px"},{"ck":"right","ak":"right"},{"ck":"middle","ak":"middle"},{"ck":"caption","ak":"caption"}],"size":"50x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
 +<figure class="mw-halign-right" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"width","ak":"50x50px"},{"ck":"right","ak":"right"},{"ck":"middle","ak":"middle"},{"ck":"caption","ak":"caption"}],"size":"50x50"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="6" width="50" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"6","width":"50"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>caption</figcaption></figure>
  !! end
  
  !! test
 -Parsoid-specific image handling - framed image with specific size and caption
 -(size is ignored)
 +Parsoid-specific image handling - framed image with specific size and caption (size is ignored)
  !! options
  parsoid=wt2html,wt2wt,html2html
  !! wikitext
  !! end
  
  !! test
 -Parsoid-specific image handling - framed image with specific size, halign, valign, and caption
 -(size is ignored)
 +Parsoid-specific image handling - framed image with specific size, halign, valign, and caption (size is ignored)
  !! options
 -parsoid=wt2html,wt2wt,html2html
 +parsoid=wt2html,html2html
  !! wikitext
  [[File:Foobar.jpg|left|baseline|frame|500x50px|caption]]
  !! html/parsoid
 -<figure class="mw-halign-left mw-valign-baseline" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>caption</figcaption></figure>
 +<figure class="mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>caption</figcaption></figure>
  !! end
  
  !! test
@@@ -16454,9 -15525,9 +16454,9 @@@ T93580: 1. Templated <ref> inside bloc
  
  <references />
  !! html/parsoid
 -<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
 +<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
  
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
  !! end
  
  !! test
@@@ -16466,9 -15537,9 +16466,9 @@@ T93580: 2. <ref> inside inline image
  
  <references />
  !! html/parsoid
 -<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"body\":{\"id\":\"mw-reference-text-cite_note-1\"},\"attrs\":{}}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"attrs\":{},\"body\":{\"id\":\"mw-reference-text-cite_note-1\"}}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
  
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
  !! end
  
  !! test
@@@ -16478,9 -15549,9 +16478,9 @@@ T93580: 3. Templated <ref> inside inlin
  
  <references />
  !! html/parsoid
 -<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 +<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
  
 -<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 +<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
  !! end
  
  ###
@@@ -16883,7 -15954,7 +16883,7 @@@ parsoid=wt2htm
  * So should this
  
  {{echo|[[Category:Foo]] and this should be part of the same list item}}
 -!! html
 +!! html/php+tidy
  <ul><li>This and this should be part of the same list item</li>
  <li>So should this and this should be part of the same list item</li></ul>
  !! html/parsoid
  !! test
  3. Categories and newlines: newline suppression for last list item should RT properly
  !! wikitext
 -* a
 -* b 
 +*a
 +*b
     
  [[Category:Foo]]
     
  [[Category:Bar]]
  [[Category:Baz]]
 +
 +:c
 +
 +[[Category:C]]
 +
 +;d
 +
 +[[Category:D]]
  !! html/parsoid
 -<ul><li> a</li>
 -<li> b</li></ul> 
 +<ul><li>a</li>
 +<li>b</li></ul>
     
 -<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
 +<link rel="mw:PageProp/Category" href="./Category:Foo"/>
     
 -<link rel="mw:PageProp/Category" href="./Category:Bar" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
 -<link rel="mw:PageProp/Category" href="./Category:Baz" data-parsoid='{"stx":"simple","a":{"href":"./Category:Baz"},"sa":{"href":"Category:Baz"}}'/>
 +<link rel="mw:PageProp/Category" href="./Category:Bar"/>
 +<link rel="mw:PageProp/Category" href="./Category:Baz"/>
 +
 +<dl><dd>c</dd></dl>
 +
 +<link rel="mw:PageProp/Category" href="./Category:C"/>
 +
 +<dl><dt>d</dt></dl>
 +
 +<link rel="mw:PageProp/Category" href="./Category:D"/>
  !! end
  
  !! test
  4. Categories and newlines: newline suppression for last list item should RT properly
  !! wikitext
 -* a
 -**** b
 +*a
 +****b
  
  [[Category:Foo]]
  !! html/parsoid
 -<ul><li> a
 -<ul><li><ul><li><ul><li> b</li></ul></li></ul></li></ul></li></ul>
 +<ul><li>a
 +<ul><li><ul><li><ul><li>b</li></ul></li></ul></li></ul></li></ul>
  
  <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
  !! end
  !! options
  parsoid=wt2html
  !! wikitext
 -* a
 -** b
 +*a
 +**b
  [[Category:Foo]]
 -* c
 -** d
 +*c
 +**d
  [[Category:Foo]]
  !! html/parsoid
 -<ul><li> a
 -<ul><li> b
 +<ul><li>a
 +<ul><li>b
  <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul></li>
 -<li> c
 -<ul><li> d</li></ul></li></ul>
 +<li>c
 +<ul><li>d</li></ul></li></ul>
  <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/>
  !! end
  
  !! options
  parsoid=wt2html
  !! wikitext
 -* a [[Category:Foo]]
 +*a [[Category:Foo]]
  !! html/parsoid
 -<ul><li>a <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
 +<ul><li>a<link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
  !! end
  
  # This test also demonstrates because of newline+category tunneling
  !! test
  7. Categories and newlines: migrateTrailingCategories dom pass should leave template content alone
  !! wikitext
 -* {{echo|a
 +*{{echo|a
  [[Category:Foo]]}}
  !! html/parsoid
 -<ul><li> <span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n[[Category:Foo]]"}},"i":0}}]}'>a
 +<ul><li><span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n[[Category:Foo]]"}},"i":0}}]}'>a
  </span><link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"}}'/></li></ul>
  !! end
  
  !! test
  8. Categories and newlines: migrateTrailingCategories dom pass should not get tripped by intervening templates
  !! wikitext
 -* a
 +*a
  
  {{echo|[[Category:Foo]]
  [[Category:Bar]]}}
  [[Category:Baz]]
  !! html/parsoid
 -<ul><li> a</li></ul>
 +<ul><li>a</li></ul>
  
  <link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"simple","a":{"href":"./Category:Foo"},"sa":{"href":"Category:Foo"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]]\n[[Category:Bar]]"}},"i":0}}]}'/><span about="#mwt1">
  </span><link rel="mw:PageProp/Category" href="./Category:Bar" about="#mwt1" data-parsoid='{"stx":"simple","a":{"href":"./Category:Bar"},"sa":{"href":"Category:Bar"}}'/>
  !! end
  
  !! test
 -9. Categories and newlines: should behave properly with linkprefix (T87753)
 +Categories and newlines: migrateTrailingCategories dom pass should not get tripped by comments and whitespace
 +!! wikitext
 +*a
 +
 +[[Category:Bar]]<!--boo1--> <!--boo2-->
 +[[Category:Baz]]<!--boo3--> <!--boo4-->
 +!! html/parsoid
 +<ul><li>a</li></ul>
 +
 +<link rel="mw:PageProp/Category" href="./Category:Bar"/><!--boo1--> <!--boo2-->
 +<link rel="mw:PageProp/Category" href="./Category:Baz"/><!--boo3--> <!--boo4-->
 +!! end
 +
 +!! test
 +Categories and newlines: should behave properly with linkprefix (T87753)
  !! options
  language=ar
  !! wikitext
@@@ -17045,7 -16086,7 +17045,7 @@@ foo bar</p
  !! end
  
  !! test
 -10. No regressions on internal links following category (T174639)
 +No regressions on internal links following category (T174639)
  !! options
  parsoid=wt2html,html2html
  !! wikitext
@@@ -17096,15 -16137,13 +17096,15 @@@ Category links with multiple namespace
  
  !! test
  Parsoid: Serialize link to category page with colon escape
 -!! options
 -parsoid
  !! wikitext
  
  [[:Category:Foo]]
  [[:Category:Foo|Bar]]
 -!! html
 +!! html/php+tidy
 +<p><a href="/index.php?title=Category:Foo&amp;action=edit&amp;redlink=1" class="new" title="Category:Foo (page does not exist)">Category:Foo</a>
 +<a href="/index.php?title=Category:Foo&amp;action=edit&amp;redlink=1" class="new" title="Category:Foo (page does not exist)">Bar</a>
 +</p>
 +!! html/parsoid
  <p>
  <a rel="mw:WikiLink" href="./Category:Foo" title="Category:Foo">Category:Foo</a>
  <a rel="mw:WikiLink" href="./Category:Foo" title="Category:Foo">Bar</a>
@@@ -17151,15 -16190,13 +17151,15 @@@ x[[es:Foo]]
  
  !! test
  Parsoid: Serialize link to file page with colon escape
 -!! options
 -parsoid
  !! wikitext
  
  [[:File:Foo.png]]
  [[:File:Foo.png|Bar]]
 -!! html
 +!! html/php+tidy
 +<p><a href="/index.php?title=File:Foo.png&amp;action=edit&amp;redlink=1" class="new" title="File:Foo.png (page does not exist)">File:Foo.png</a>
 +<a href="/index.php?title=File:Foo.png&amp;action=edit&amp;redlink=1" class="new" title="File:Foo.png (page does not exist)">Bar</a>
 +</p>
 +!! html/parsoid
  <p>
  <a rel="mw:WikiLink" href="./File:Foo.png" title="File:Foo.png">File:Foo.png</a>
  <a rel="mw:WikiLink" href="./File:Foo.png" title="File:Foo.png">Bar</a>
  
  !! test
  Parsoid: Serialize a genuine category link without colon escape
 -!! options
 -parsoid
  !! wikitext
  [[Category:Foo]]
  [[Category:Foo|Bar]]
 -!! html
 +!! html/php+tidy
 +!! html/parsoid
  <link rel="mw:PageProp/Category" href="./Category:Foo">
  <link rel="mw:PageProp/Category" href="./Category:Foo#Bar">
  !! end
@@@ -17249,7 -16287,7 +17249,7 @@@ es:1 fr:
  !! test
  Basic section headings
  !! wikitext
 -== Headline 1 ==
 +==Headline 1==
  Some text
  
  ==Headline 2==
@@@ -17271,16 -16309,16 +17271,16 @@@ Blah bla
  !! test
  Section headings with TOC
  !! wikitext
 -== Headline 1 ==
 -=== Subheadline 1 ===
 -===== Skipping a level =====
 -====== Skipping a level ======
 +==Headline 1==
 +===Subheadline 1===
 +=====Skipping a level=====
 +======Skipping a level======
  
 -== Headline 2 ==
 +==Headline 2==
  Some text
  ===Another headline===
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Headline_1"><span class="tocnumber">1</span> <span class="toctext">Headline 1</span></a>
  <ul>
  TOC anchors don't collide
  !! wikitext
  __FORCETOC__
 -== Headline 2 ==
 -== Headline ==
 -== Headline 2 ==
 -== Headline ==
 +==Headline 2==
 +==Headline==
 +==Headline 2==
 +==Headline==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Headline_2"><span class="tocnumber">1</span> <span class="toctext">Headline 2</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#Headline"><span class="tocnumber">2</span> <span class="toctext">Headline</span></a></li>
@@@ -17346,18 -16384,18 +17346,18 @@@ Handling of sections up to level 6 and 
  !! options
  parsoid=wt2html
  !! wikitext
 -= Level 1 Heading=
 -== Level 2 Heading==
 -=== Level 3 Heading===
 -==== Level 4 Heading====
 -===== Level 5 Heading=====
 -====== Level 6 Heading======
 -======= Level 7 Heading=======
 -======== Level 8 Heading========
 -========= Level 9 Heading=========
 -========== Level 10 Heading==========
 -!! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +=Level 1 Heading=
 +==Level 2 Heading==
 +===Level 3 Heading===
 +====Level 4 Heading====
 +=====Level 5 Heading=====
 +======Level 6 Heading======
 +=======Level 7 Heading=======
 +========Level 8 Heading========
 +=========Level 9 Heading=========
 +==========Level 10 Heading==========
 +!! html/php
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Level_1_Heading"><span class="tocnumber">1</span> <span class="toctext">Level 1 Heading</span></a>
  <ul>
  <li class="toclevel-5 tocsection-5"><a href="#Level_5_Heading"><span class="tocnumber">1.1.1.1.1</span> <span class="toctext">Level 5 Heading</span></a>
  <ul>
  <li class="toclevel-6 tocsection-6"><a href="#Level_6_Heading"><span class="tocnumber">1.1.1.1.1.1</span> <span class="toctext">Level 6 Heading</span></a></li>
 -<li class="toclevel-6 tocsection-7"><a href="#.3D_Level_7_Heading.3D"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">= Level 7 Heading=</span></a></li>
 -<li class="toclevel-6 tocsection-8"><a href="#.3D.3D_Level_8_Heading.3D.3D"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">== Level 8 Heading==</span></a></li>
 -<li class="toclevel-6 tocsection-9"><a href="#.3D.3D.3D_Level_9_Heading.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">=== Level 9 Heading===</span></a></li>
 -<li class="toclevel-6 tocsection-10"><a href="#.3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.5</span> <span class="toctext">==== Level 10 Heading====</span></a></li>
 +<li class="toclevel-6 tocsection-7"><a href="#.3DLevel_7_Heading.3D"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">=Level 7 Heading=</span></a></li>
 +<li class="toclevel-6 tocsection-8"><a href="#.3D.3DLevel_8_Heading.3D.3D"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">==Level 8 Heading==</span></a></li>
 +<li class="toclevel-6 tocsection-9"><a href="#.3D.3D.3DLevel_9_Heading.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">===Level 9 Heading===</span></a></li>
 +<li class="toclevel-6 tocsection-10"><a href="#.3D.3D.3D.3DLevel_10_Heading.3D.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.5</span> <span class="toctext">====Level 10 Heading====</span></a></li>
  </ul>
  </li>
  </ul>
  <h4><span class="mw-headline" id="Level_4_Heading">Level 4 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=4" title="Edit section: Level 4 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h4>
  <h5><span class="mw-headline" id="Level_5_Heading">Level 5 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=5" title="Edit section: Level 5 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h5>
  <h6><span class="mw-headline" id="Level_6_Heading">Level 6 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=6" title="Edit section: Level 6 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 -<h6><span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=7" title="Edit section: = Level 7 Heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 -<h6><span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=8" title="Edit section: == Level 8 Heading==">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 -<h6><span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=9" title="Edit section: === Level 9 Heading===">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 -<h6><span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=10" title="Edit section: ==== Level 10 Heading====">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 +<h6><span class="mw-headline" id=".3DLevel_7_Heading.3D">=Level 7 Heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=7" title="Edit section: =Level 7 Heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 +<h6><span class="mw-headline" id=".3D.3DLevel_8_Heading.3D.3D">==Level 8 Heading==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=8" title="Edit section: ==Level 8 Heading==">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 +<h6><span class="mw-headline" id=".3D.3D.3DLevel_9_Heading.3D.3D.3D">===Level 9 Heading===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=9" title="Edit section: ===Level 9 Heading===">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
 +<h6><span class="mw-headline" id=".3D.3D.3D.3DLevel_10_Heading.3D.3D.3D.3D">====Level 10 Heading====</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=10" title="Edit section: ====Level 10 Heading====">edit</a><span class="mw-editsection-bracket">]</span></span></h6>
  
  !! html/parsoid
 -<h1 id="Level_1_Heading" data-parsoid='{}'> Level 1 Heading</h1>
 -<h2 id="Level_2_Heading" data-parsoid='{}'> Level 2 Heading</h2>
 -<h3 id="Level_3_Heading" data-parsoid='{}'> Level 3 Heading</h3>
 -<h4 id="Level_4_Heading" data-parsoid='{}'> Level 4 Heading</h4>
 -<h5 id="Level_5_Heading" data-parsoid='{}'> Level 5 Heading</h5>
 -<h6 id="Level_6_Heading" data-parsoid='{}'> Level 6 Heading</h6>
 -<h6 id="=_Level_7_Heading=" data-parsoid='{}'><span id=".3D_Level_7_Heading.3D" typeof="mw:FallbackId"></span>= Level 7 Heading=</h6>
 -<h6 id="==_Level_8_Heading==" data-parsoid='{}'><span id=".3D.3D_Level_8_Heading.3D.3D" typeof="mw:FallbackId"></span>== Level 8 Heading==</h6>
 -<h6 id="===_Level_9_Heading===" data-parsoid='{}'><span id=".3D.3D.3D_Level_9_Heading.3D.3D.3D" typeof="mw:FallbackId"></span>=== Level 9 Heading===</h6>
 -<h6 id="====_Level_10_Heading====" data-parsoid='{}'><span id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D" typeof="mw:FallbackId"></span>==== Level 10 Heading====</h6>
 +<h1 id="Level_1_Heading" data-parsoid='{}'>Level 1 Heading</h1>
 +<h2 id="Level_2_Heading" data-parsoid='{}'>Level 2 Heading</h2>
 +<h3 id="Level_3_Heading" data-parsoid='{}'>Level 3 Heading</h3>
 +<h4 id="Level_4_Heading" data-parsoid='{}'>Level 4 Heading</h4>
 +<h5 id="Level_5_Heading" data-parsoid='{}'>Level 5 Heading</h5>
 +<h6 id="Level_6_Heading" data-parsoid='{}'>Level 6 Heading</h6>
 +<h6 id="=Level_7_Heading=" data-parsoid='{}'><span id=".3DLevel_7_Heading.3D" typeof="mw:FallbackId"></span>=Level 7 Heading=</h6>
 +<h6 id="==Level_8_Heading==" data-parsoid='{}'><span id=".3D.3DLevel_8_Heading.3D.3D" typeof="mw:FallbackId"></span>==Level 8 Heading==</h6>
 +<h6 id="===Level_9_Heading===" data-parsoid='{}'><span id=".3D.3D.3DLevel_9_Heading.3D.3D.3D" typeof="mw:FallbackId"></span>===Level 9 Heading===</h6>
 +<h6 id="====Level_10_Heading====" data-parsoid='{}'><span id=".3D.3D.3D.3DLevel_10_Heading.3D.3D.3D.3D" typeof="mw:FallbackId"></span>====Level 10 Heading====</h6>
  !! end
  
  !! test
  TOC regression (T11764)
  !! wikitext
 -== title 1 ==
 -=== title 1.1 ===
 -==== title 1.1.1 ====
 -=== title 1.2 ===
 -== title 2 ==
 -=== title 2.1 ===
 +==title 1==
 +===title 1.1===
 +====title 1.1.1====
 +===title 1.2===
 +==title 2==
 +===title 2.1===
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
  <ul>
@@@ -17456,7 -16494,7 +17456,7 @@@ TOC for heading containing <span id="..
  __FORCETOC__
  ==<span id="old-anchor"></span>New title==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#New_title"><span class="tocnumber">1</span> <span class="toctext">New title</span></a></li>
  </ul>
@@@ -17471,14 -16509,14 +17471,14 @@@ TOC with wgMaxTocLevel=3 (T8204
  !! options
  wgMaxTocLevel=3
  !! wikitext
 -== title 1 ==
 -=== title 1.1 ===
 -==== title 1.1.1 ====
 -=== title 1.2 ===
 -== title 2 ==
 -=== title 2.1 ===
 +==title 1==
 +===title 1.1===
 +====title 1.1.1====
 +===title 1.2===
 +==title 2==
 +===title 2.1===
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
  <ul>
@@@ -17514,7 -16552,7 +17514,7 @@@ wgMaxTocLevel=
  ====Section 1.1.1.1====
  ==Section 2==
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a>
  <ul>
  !! test
  Resolving duplicate section names
  !! wikitext
 -== Foo bar ==
 -== Foo bar ==
 +==Foo bar==
 +==Foo bar==
  !! html
  <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  <h2><span class="mw-headline" id="Foo_bar_2">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  !! test
  Resolving duplicate section names with differing case (T12721)
  !! wikitext
 -== Foo bar ==
 -== Foo Bar ==
 +==Foo bar==
 +==Foo Bar==
  !! html
  <h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  <h2><span class="mw-headline" id="Foo_Bar_2">Foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
@@@ -17603,11 -16641,11 +17603,11 @@@ Link inside a section headin
  TOC regression (T14077)
  !! wikitext
  __TOC__
 -== title 1 ==
 -=== title 1.1 ===
 -== title 2 ==
 +==title 1==
 +===title 1.1===
 +==title 2==
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a>
  <ul>
@@@ -17666,24 -16704,24 +17666,24 @@@ Header with special characters (T27462
  !! wikitext
  The tooltips shall not show entities to the user (ie. be double escaped)
  
 -== text > text ==
 +==text > text==
  section 1
  
 -== text < text ==
 +==text < text==
  section 2
  
 -== text & text ==
 +==text & text==
  section 3
  
 -== text ' text ==
 +==text ' text==
  section 4
  
 -== text " text ==
 +==text " text==
  section 5
  !! html/php
  <p>The tooltips shall not show entities to the user (ie. be double escaped)
  </p>
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#text_.3E_text"><span class="tocnumber">1</span> <span class="toctext">text &gt; text</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#text_.3C_text"><span class="tocnumber">2</span> <span class="toctext">text &lt; text</span></a></li>
  !! html/parsoid
  <p>The tooltips shall not show entities to the user (ie. be double escaped)</p>
  
 -<h2 id="text_>_text"><span id="text_.3E_text" typeof="mw:FallbackId"></span> text > text </h2>
 +<h2 id="text_>_text"><span id="text_.3E_text" typeof="mw:FallbackId"></span>text > text</h2>
  <p>section 1</p>
  
 -<h2 id="text_&lt;_text"><span id="text_.3C_text" typeof="mw:FallbackId"></span> text &lt; text </h2>
 +<h2 id="text_&lt;_text"><span id="text_.3C_text" typeof="mw:FallbackId"></span>text &lt; text</h2>
  <p>section 2</p>
  
 -<h2 id="text_&amp;_text"><span id="text_.26_text" typeof="mw:FallbackId"></span> text &amp; text </h2>
 +<h2 id="text_&amp;_text"><span id="text_.26_text" typeof="mw:FallbackId"></span>text &amp; text</h2>
  <p>section 3</p>
  
 -<h2 id="text_'_text"><span id="text_.27_text" typeof="mw:FallbackId"></span> text ' text </h2>
 +<h2 id="text_'_text"><span id="text_.27_text" typeof="mw:FallbackId"></span>text ' text</h2>
  <p>section 4</p>
  
 -<h2 id='text_"_text'><span id="text_.22_text" typeof="mw:FallbackId"></span> text " text </h2>
 +<h2 id='text_"_text'><span id="text_.22_text" typeof="mw:FallbackId"></span>text " text</h2>
  <p>section 5</p>
  !! end
  
@@@ -17732,22 -16770,22 +17732,22 @@@ Header with space, plus and underscore 
  !! wikitext
  Id should not contain + for spaces
  
 -== Space between Text ==
 +==Space between Text==
  section 1
  
 -== Space-Entity&#32;between&#32;Text ==
 +==Space-Entity&#32;between&#32;Text==
  section 2
  
 -== Plus+between+Text ==
 +==Plus+between+Text==
  section 3
  
 -== Plus-Entity&#43;between&#43;Text ==
 +==Plus-Entity&#43;between&#43;Text==
  section 4
  
 -== Underscore_between_Text ==
 +==Underscore_between_Text==
  section 5
  
 -== Underscore-Entity&#95;between&#95;Text ==
 +==Underscore-Entity&#95;between&#95;Text==
  section 6
  
  [[#Space between Text]]
  !! html/php
  <p>Id should not contain + for spaces
  </p>
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Space_between_Text"><span class="tocnumber">1</span> <span class="toctext">Space between Text</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#Space-Entity_between_Text"><span class="tocnumber">2</span> <span class="toctext">Space-Entity&#32;between&#32;Text</span></a></li>
  !! html/parsoid
  <p>Id should not contain + for spaces</p>
  
 -<h2 id="Space_between_Text"> Space between Text </h2>
 +<h2 id="Space_between_Text">Space between Text</h2>
  <p>section 1</p>
  
 -<h2 id="Space-Entity_between_Text"> Space-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#32;","srcContent":" "}'> </span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#32;","srcContent":" "}'> </span>Text </h2>
 +<h2 id="Space-Entity_between_Text">Space-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#32;","srcContent":" "}'> </span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#32;","srcContent":" "}'> </span>Text</h2>
  <p>section 2</p>
  
 -<h2 id="Plus+between+Text"><span id="Plus.2Bbetween.2BText" typeof="mw:FallbackId"></span> Plus+between+Text </h2>
 +<h2 id="Plus+between+Text"><span id="Plus.2Bbetween.2BText" typeof="mw:FallbackId"></span>Plus+between+Text</h2>
  <p>section 3</p>
  
 -<h2 id="Plus-Entity+between+Text"><span id="Plus-Entity.2Bbetween.2BText" typeof="mw:FallbackId"></span> Plus-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#43;","srcContent":"+"}'>+</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#43;","srcContent":"+"}'>+</span>Text </h2>
 +<h2 id="Plus-Entity+between+Text"><span id="Plus-Entity.2Bbetween.2BText" typeof="mw:FallbackId"></span>Plus-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#43;","srcContent":"+"}'>+</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#43;","srcContent":"+"}'>+</span>Text</h2>
  <p>section 4</p>
  
 -<h2 id="Underscore_between_Text"> Underscore_between_Text </h2>
 +<h2 id="Underscore_between_Text">Underscore_between_Text</h2>
  <p>section 5</p>
  
 -<h2 id="Underscore-Entity_between_Text"> Underscore-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>Text </h2>
 +<h2 id="Underscore-Entity_between_Text">Underscore-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>Text</h2>
  <p>section 6</p>
  
 -<p><a rel="mw:WikiLink" href="./Main_Page#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
 -<a rel="mw:WikiLink" href="./Main_Page#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
 -<a rel="mw:WikiLink" href="./Main_Page#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
 -<a rel="mw:WikiLink" href="./Main_Page#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
 -<a rel="mw:WikiLink" href="./Main_Page#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
 -<a rel="mw:WikiLink" href="./Main_Page#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
 +<p><a rel="mw:WikiLink" href="./Parser_test#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
 +<a rel="mw:WikiLink" href="./Parser_test#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
 +<a rel="mw:WikiLink" href="./Parser_test#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
 +<a rel="mw:WikiLink" href="./Parser_test#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
 +<a rel="mw:WikiLink" href="./Parser_test#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
 +<a rel="mw:WikiLink" href="./Parser_test#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
  !! end
  
  # Parsoid html2wt disabled because it adds padding spaces around =
@@@ -17835,7 -16873,7 +17835,7 @@@ parsoid=wt2html,wt2wt,html2htm
  =''italic'' heading==
  ==''italic'' heading=
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#foo.3D"><span class="tocnumber">1</span> <span class="toctext">foo=</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#.3Dfoo"><span class="tocnumber">2</span> <span class="toctext">=foo</span></a></li>
@@@ -17861,16 -16899,16 +17861,16 @@@ HTML headers vs TOC (T25393
  (__NOEDITSECTION__ for clearer output, doesn't matter here)
  !! wikitext
  <h1>Header 1</h1>
 -== Header 1.1 ==
 -== Header 1.2 ==
 +==Header 1.1==
 +==Header 1.2==
  
  <h1>Header 2
  </h1>
 -== Header 2.1 ==
 -== Header 2.2 ==
 +==Header 2.1==
 +==Header 2.2==
  __NOEDITSECTION__
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1"><a href="#Header_1"><span class="tocnumber">1</span> <span class="toctext">Header 1</span></a>
  <ul>
  <h1><span class="mw-headline" id="Header_1">Header 1</span></h1>
  <h2><span class="mw-headline" id="Header_1.1">Header 1.1</span></h2>
  <h2><span class="mw-headline" id="Header_1.2">Header 1.2</span></h2>
 -<h1><span class="mw-headline" id="Header_2">Header 2</span></h1>
 +<h1><span class="mw-headline" id="Header_2">Header 2
 +</span></h1>
  <h2><span class="mw-headline" id="Header_2.1">Header 2.1</span></h2>
  <h2><span class="mw-headline" id="Header_2.2">Header 2.2</span></h2>
  
  !! html/parsoid
  <h1 id="Header_1" data-parsoid='{"stx":"html"}'>Header 1</h1>
 -<h2 id="Header_1.1" data-parsoid='{}'> Header 1.1 </h2>
 -<h2 id="Header_1.2" data-parsoid='{}'> Header 1.2 </h2>
 +<h2 id="Header_1.1" data-parsoid='{}'>Header 1.1</h2>
 +<h2 id="Header_1.2" data-parsoid='{}'>Header 1.2</h2>
  
  <h1 id="Header_2" data-parsoid='{"stx":"html"}'>Header 2
  </h1>
 -<h2 id="Header_2.1" data-parsoid='{}'> Header 2.1 </h2>
 -<h2 id="Header_2.2" data-parsoid='{}'> Header 2.2 </h2>
 +<h2 id="Header_2.1" data-parsoid='{}'>Header 2.1</h2>
 +<h2 id="Header_2.2" data-parsoid='{}'>Header 2.2</h2>
  <meta property="mw:PageProp/noeditsection"/>
  !! end
  
@@@ -18067,17 -17104,17 +18067,17 @@@ table with multiple empty attribute val
  parsoid=wt2html,html2html
  !! wikitext
  {| title= id=
 -| hi
 +|hi
  |}
  !! html/php
  <table title="id=">
  <tr>
 -<td> hi
 +<td>hi
  </td></tr></table>
  
  !! html/parsoid
  <table title="id=">
 -<tbody><tr><td> hi</td></tr>
 +<tbody><tr><td>hi</td></tr>
  </tbody></table>
  !! end
  
@@@ -18118,12 -17155,12 +18118,12 @@@ HTML multiple attributes correctio
  Table multiple attributes correction
  !! wikitext
  {|
 -!+ class="error" class="awesome"| status
 +!+ class="error" class="awesome"|status
  |}
  !! html
  <table>
  <tr>
 -<th class="awesome"> status
 +<th class="awesome">status
  </th></tr></table>
  
  !!end
@@@ -18323,9 -17360,9 +18323,9 @@@ Media lin
  <a href="http://example.com/images/0/00/Video.ogv" class="internal" title="Video.ogv">Media:Video.ogv</a>
  </p>
  !! html/parsoid
 -<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg">Media:Foobar.jpg</a>
 -<a rel="mw:MediaLink" href="//example.com/images/0/00/Video.ogv" title="Video.ogv">Media:Video.ogv</a>
 -<a rel="mw:MediaLink" href="//example.com/images/0/00/Video.ogv" title="Video.ogv" data-parsoid='{"a":{"namespace":"Media"},"sa":{"namespace":":Media"}}'>Media:Video.ogv</a></p>
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Media:Foobar.jpg" title="Foobar.jpg">Media:Foobar.jpg</a>
 +<a rel="mw:MediaLink" href="//example.com/images/0/00/Video.ogv" resource="./Media:Video.ogv" title="Video.ogv">Media:Video.ogv</a>
 +<a rel="mw:MediaLink" href="//example.com/images/0/00/Video.ogv" resource="./Media:Video.ogv" title="Video.ogv" data-parsoid='{"a":{"resource":"./Media:Video.ogv"},"sa":{"resource":":Media:Video.ogv"}}'>Media:Video.ogv</a></p>
  !! end
  
  !! test
@@@ -18336,24 -17373,7 +18336,24 @@@ Media link with tex
  <p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">A neat file to look at</a>
  </p>
  !! html/parsoid
 -<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg">A neat file to look at</a></p>
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Media:Foobar.jpg" title="Foobar.jpg">A neat file to look at</a></p>
 +!! end
 +
 +!! test
 +Localized media link
 +!! options
 +language=is
 +!! wikitext
 +[[Miðill:Foobar.jpg]]
 +
 +[[Miðill:Foobar.jpg|Icelandic]]
 +!! html/php
 +<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Miðill:Foobar.jpg</a>
 +</p><p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Icelandic</a>
 +</p>
 +!! html/parsoid
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Miðill:Foobar.jpg" title="Foobar.jpg">Miðill:Foobar.jpg</a></p>
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Miðill:Foobar.jpg" title="Foobar.jpg">Icelandic</a></p>
  !! end
  
  # FIXME: this is still bad HTML tag nesting
  # Parsoid & Remex fix the p-wrapping since they operate on the DOM.
  !! test
  Media link with nasty text
 +!! options
 +parsoid=wt2html,html2html
  !! wikitext
  [[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]]
  !! html/php
  <a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a>
  
 -!! html+php/tidy
 -<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link</a></p>
 -<div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div>
 +!! html/php+tidy
 +<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link</a></p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg"><div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div></a>
 +!! html/parsoid
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Media:Foobar.jpg" title="Foobar.jpg">Safe Link</a></p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" resource="./Media:Foobar.jpg" title="Foobar.jpg"><div style="display:none" data-parsoid='{"stx":"html"}'>" onmouseover="alert(document.cookie)" onfoo="</div></a>
 +!! end
 +
 +!! test
 +Media link from missing resource (parsoid-only)
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<a rel="mw:MediaLink" href="http://example.com/images/3/3a/Foobar.jpg">Bat!</a>
 +!! wikitext
 +[[Media:Foobar.jpg|Bat!]]
 +!! end
 +
 +!! test
 +Media link from missing resource, localized (parsoid-only)
 +!! options
 +parsoid=html2wt
 +language=is
 +!! html/parsoid
 +<a rel="mw:MediaLink" href="http://example.com/images/3/3a/Foobar.jpg">Bat!</a>
 +!! wikitext
 +[[Miðill:Foobar.jpg|Bat!]]
 +!! end
 +
 +# This is a sanity test to ensure we don't crash or choke when given
 +# old cached 1.7.0 HTML for media links; we don't require that the
 +# result be "valid" because wt2wt was completely broken in 1.7.0
 +!! test
 +Media link from old 1.7.0 DOM spec (crash test, parsoid-only) T198511
 +!! options
 +parsoid=html2wt
  !! html/parsoid
 -<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg" data-parsoid='{"autoInsertedEnd":true}'>Safe Link</a></p><div style="display:none" data-parsoid='{"stx":"html"}'><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg" data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'>" onmouseover="alert(document.cookie)" onfoo="</a></div>
 +<p>This is what Parsoid would emit (and we still handle this HTML fine):</p>
 +<p><a rel="mw:MediaLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg">A neat file to look at</a></p>
 +<p>But VisualEditor would mangle the rel attribute, and give us back this:</p>
 +<p><a rel="mw:ExtLink" href="//example.com/images/3/3a/Foobar.jpg" title="Foobar.jpg">A neat file to look at</a></p>
 +<p>But at least we don't crash when trying to handle the mangled HTML!</p>
 +!! wikitext
 +This is what Parsoid would emit (and we still handle this HTML fine):
 +
 +[[Media:Foobar.jpg|A neat file to look at]]
 +
 +But VisualEditor would mangle the rel attribute, and give us back this:
 +
 +[//example.com/images/3/3a/Foobar.jpg A neat file to look at]
  
 +But at least we don't crash when trying to handle the mangled HTML!
  !! end
  
  !! test
@@@ -18430,8 -17404,8 +18430,8 @@@ Media link to nonexistent file (T3702
  <a href="/index.php?title=Special:Upload&amp;wpDestFile=No_such_file.jpg" class="new" title="No such file.jpg">Media:No_such file.jpg</a>
  </p>
  !! html/parsoid
 -<p><a rel="mw:MediaLink" href="./Special:FilePath/No_such.jpg" title="No such.jpg" typeof="mw:Error" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}' data-parsoid='{"a":{"fileName":"No_such.jpg"},"sa":{"fileName":"No such.jpg"}}'>Media:No such.jpg</a>
 -<a rel="mw:MediaLink" href="./Special:FilePath/No_such_file.jpg" title="No such file.jpg" typeof="mw:Error" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}' data-parsoid='{"a":{"fileName":"No_such_file.jpg"},"sa":{"fileName":"No_such file.jpg"}}'>Media:No_such file.jpg</a></p>
 +<p><a rel="mw:MediaLink" href="./Special:FilePath/No_such.jpg" resource="./Media:No_such.jpg" title="No such.jpg" typeof="mw:Error" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}' data-parsoid='{"a":{"resource":"./Media:No_such.jpg"},"sa":{"resource":"Media:No such.jpg"}}'>Media:No such.jpg</a>
 +<a rel="mw:MediaLink" href="./Special:FilePath/No_such_file.jpg" resource="./Media:No_such_file.jpg" title="No such file.jpg" typeof="mw:Error" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}' data-parsoid='{"a":{"resource":"./Media:No_such_file.jpg"},"sa":{"resource":"Media:No_such file.jpg"}}'>Media:No_such file.jpg</a></p>
  !! end
  
  !! test
@@@ -18938,12 -17912,12 +18938,12 @@@ MSIE 6 CSS safety test: Repetition mark
  Table attribute legitimate extension
  !! wikitext
  {|
 -!+ style="<nowiki>color:blue</nowiki>"| status
 +!+ style="<nowiki>color:blue</nowiki>"|status
  |}
  !! html
  <table>
  <tr>
 -<th style="color:blue"> status
 +<th style="color:blue">status
  </th></tr></table>
  
  !!end
  Table attribute safety
  !! wikitext
  {|
 -!+ style="<nowiki>border-width:expression(0+alert(document.cookie))</nowiki>"| status
 +!+ style="<nowiki>border-width:expression(0+alert(document.cookie))</nowiki>"|status
  |}
  !! html
  <table>
  <tr>
 -<th style="/* insecure input */"> status
 +<th style="/* insecure input */">status
  </th></tr></table>
  
  !! end
@@@ -19027,7 -18001,7 +19027,7 @@@ Tags which are hidden from tidiers cann
  !! end
  
  ###
 -### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension)
 +### Parser hooks (see tests/parser/ParserTestParserHook.php for the <tag> extension)
  ###
  
  !! test
@@@ -19060,7 -18034,7 +19060,7 @@@ array 
  </pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":null}' data-parsoid='{}' about="#mwt2"></pre>
 +<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{}}' data-parsoid='{}' about="#mwt2"></pre>
  !! end
  
  !! test
@@@ -19075,7 -18049,7 +19075,7 @@@ array 
  </pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":null}' data-parsoid='{}' about="#mwt2"></pre>
 +<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{}}' data-parsoid='{}' about="#mwt2"></pre>
  !! end
  
  !! test
@@@ -19131,8 -18105,6 +19131,8 @@@ array 
  
  !! test
  Parser hook: nested tags
 +!! options
 +parsoid=wt2html
  !! wikitext
  <tag><tag></tag></tag>
  !! html/php
@@@ -19142,14 -18114,8 +19142,14 @@@ array 
  )
  </pre>&lt;/tag&gt;
  
 +!! html/php+tidy
 +<pre>'<tag>'
 +array (
 +)
 +</tag></pre><p>&lt;/tag&gt;
 +</p>
  !! html/parsoid
 -<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"&lt;tag>"}}' data-parsoid='{}' about="#mwt2"></pre>&lt;/tag>
 +<pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"&lt;tag>"}}'></pre><p>&lt;/tag></p>
  !! end
  
  !! test
@@@ -19225,7 -18191,7 +19225,7 @@@ array 
  </pre>text
  
  !! html/parsoid
 -<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"foo":"bar"},"body":null}' data-parsoid='{}' about="#mwt2"></pre>text
 +<pre typeof="mw:Extension/tag" about="#mwt2" data-mw='{"name":"tag","attrs":{"foo":"bar"}}'></pre><p>text</p>
  !! end
  
  ## </tag> should be output literally since there is no matching tag that begins it
@@@ -19252,7 -18218,7 +19252,7 @@@ array 
  &lt;/tag&gt;
  </p>
  !! html/parsoid
 -<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"width":"200","height":"100","depth":"50","square":""},"body":null}' about="#mwt2"></pre><p>other stuff
 +<pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{"width":"200","height":"100","depth":"50","square":""}}' about="#mwt2"></pre><p>other stuff
  &lt;/tag></p>
  !! end
  
@@@ -19275,29 -18241,8 +19275,29 @@@ this is a '''test''
  <p>this is a <b>test</b></p>
  !! end
  
 +!! test
 +Parser hook: horizontal rule inside extension tag that outputs <pre>
 +!! wikitext
 +<tag>
 +Hello
 +<hr/>
 +Goodbye
 +</tag>
 +!! html/php
 +<pre>
 +'
 +Hello
 +<hr/>
 +Goodbye
 +'
 +array (
 +)
 +</pre>
 +
 +!! end
 +
  ###
 -### (see tests/parser/parserTestsParserHook.php for the <statictag> extension)
 +### (see tests/parser/ParserTestParserHook.php for the <statictag> extension)
  ###
  
  !! test
@@@ -19311,8 -18256,8 +19311,8 @@@ Parser hook: static parser hook not ins
  hello, world
  </p>
  !! html/parsoid
 -<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' data-parsoid='{}' about="#mwt2"></span></p>
 -<p typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"},"body":null}' data-parsoid='{}' about="#mwt4">hello, world</p>
 +<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' about="#mwt2"></span></p>
 +<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"}}' about="#mwt4">hello, world</span></p>
  !! end
  
  !! test
@@@ -19325,7 -18270,7 +19325,7 @@@ Parser hook: static parser hook inside 
  </p>
  !! html/parsoid
  <!-- <statictag&#x3E;hello, world</statictag&#x3E; -->
 -<p typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"},"body":null}' data-parsoid='{}' about='#mwt2'></p>
 +<p><span typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about='#mwt2'></span></p>
  !! end
  
  # Nested template calls; this case was broken by Parser.php rev 1.506,
@@@ -19357,6 -18302,8 +19357,6 @@@ Nested template call
  ### Sanitizer
  ###
  
 -# Remex wraps empty tag runs with p-tags.
 -# Parsoid strips them out during p-wrapping.
  !! test
  Sanitizer: Closing of open tags
  !! wikitext
  !! html/php+tidy
  <p><s></s></p><table></table>
  !! html/parsoid
 -<s></s><table></table>
 +<p><s data-parsoid='{"stx":"html"}'></s></p><table data-parsoid='{"stx":"html"}'></table>
  !! end
  
  !! test
@@@ -19382,9 -18329,10 +19382,9 @@@ Sanitizer: Closing of closed but not op
  parsoid=wt2html
  !! wikitext
  </s>
 -!! html/php+tidy
 +!! html+tidy
  <p class="mw-empty-elt">
  </p>
 -!! html/parsoid
  !! end
  
  !! test
@@@ -19400,8 -18348,6 +19400,8 @@@ Table not started</td></tr></table
  
  !! test
  Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id=""
 +!! options
 +title=[[Main Page]]
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
@@@ -19591,7 -18537,7 +19591,7 @@@ Punctuation: CSS ! important (T13874; w
  !! wikitext
  <div style="width:50% ! important">important</div>
  !! html
 -<div style="width:50% ! important">important</div>
 +<div style="width:50%&#32;! important">important</div>
  
  !!end
  
@@@ -19863,11 -18809,11 +19863,11 @@@ Fuzz testing: Parser1
  !! test
  Fuzz testing: Parser14
  !! wikitext
 -== onmouseover= ==
 +==onmouseover===
  http://__TOC__
  !! html/php
  <h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 -http://<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +http://<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
  </ul>
  
  !! html/php+tidy
  <h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2><p>
 -http://</p><div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +http://</p><div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
  </ul>
  </div>
  !! html/parsoid
 -<h2 id="onmouseover="><span id="onmouseover.3D" typeof="mw:FallbackId"></span> onmouseover= </h2>
 +<h2 id="onmouseover="><span id="onmouseover.3D" typeof="mw:FallbackId"></span>onmouseover=</h2>
  <p><a rel="mw:ExtLink" class="external free" href="http://__TOC__" data-parsoid='{"stx":"url"}'>http://__TOC__</a></p>
  !! end
  
@@@ -19893,17 -18839,19 +19893,17 @@@ parsoid=wt2html,html2htm
  !! wikitext
  ==a==
  {| STYLE=__TOC__
 -!! html
 +!! html/php
  <h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  <table style="&#95;_TOC&#95;_">
  <tr><td></td></tr>
  </table>
  
 -!! html+tidy
 +!! html/php+tidy
  <h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 -<table style="__TOC__">
 -<tr>
 -<td></td>
 -</tr>
 -</table>
 +<table style="&#95;_TOC&#95;_">
 +<tbody><tr><td></td></tr>
 +</tbody></table>
  !! html/parsoid
  <h2 id="a">a</h2>
  <table style="__TOC__"></table>
@@@ -19932,12 -18880,12 +19932,12 @@@ Fuzz testing: Parser1
  Fuzz testing: Parser21
  !! wikitext
  {|
 -! irc://{{ftp://a" onmouseover="alert('hello world');"
 +!irc://{{ftp://a" onmouseover="alert('hello world');"
  |
  !! html
  <table>
  <tr>
 -<th> <a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');"
 +<th><a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');"
  </th>
  <td>
  </td>
@@@ -19961,8 -18909,7 +19961,8 @@@ http://===r:::https://
  
  !! end
  
 -# Known to produce bad XML for now
 +## Remex doesn't account for fostered content.
 +## Known to produce bad XML for now
  !! test
  Fuzz testing: Parser24
  !! options
@@@ -19989,27 -18936,14 +19989,27 @@@ MOVE YOUR MOUSE CURSOR OVER THIS TEX
  </tr>
  </table>
  
 -!! html/parsoid
 -<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>{{{|
 -<u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true}'><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>}}}} >
 -<br style="onmouseover='alert(document.cookie);' " data-parsoid='{"stx":"html","selfClose":true}'/></u></p><p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'><u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true,"autoInsertedStart":true}'>MOVE YOUR MOUSE CURSOR OVER THIS TEXT</u></p><table data-parsoid='{"autoInsertedEnd":true}'>
 +!! html/php+tidy
  
 +{{{|
 +<u class="&#124;">}}}} &gt;
 +<br style="onmouseover=&#39;alert(document.cookie);&#39;" />
  
 +MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 +</u><table><tbody><tr>
 +<td>
 +</td>
 +</tr>
 +</tbody></table><p><u class="&#124;">
 +</u></p>
 +!! html/parsoid
 +<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>
 +{{{|
 +<u class="|" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--":""},"autoInsertedEnd":true}'><meta typeof="mw:Includes/NoInclude" data-parsoid='{"src":"&lt;noinclude>"}'/>}}}} >
 +<br style="onmouseover='alert(document.cookie);' " data-parsoid='{"stx":"html","selfClose":true}'/>
  
 -<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'></td></tr></tbody></table>
 +MOVE YOUR MOUSE CURSOR OVER THIS TEXT</u></p>
 +<table data-parsoid='{"autoInsertedEnd":true}'><tbody><tr data-parsoid='{"autoInsertedStart":true}'><td></td></tr></tbody></table>
  !! end
  
  # Note: the current result listed for this is not what the original one was,
@@@ -20093,8 -19027,8 +20093,8 @@@ parsoid=wt2htm
  <pre dir="&#10;"></pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/pre" about="#mwt2" dir="
 -" data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
 +<pre dir="
 +" typeof="mw:Extension/pre" about="#mwt2"data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
  !! end
  
  !! test
@@@ -20120,7 -19054,7 +20120,7 @@@ Templates in extension attributes are n
  <pre dir="{{echo|ltr}}"></pre>
  
  !! html/parsoid
 -<pre typeof="mw:Extension/pre" about="#mwt2" dir="{{echo|ltr}}" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
 +<pre dir="{{echo|ltr}}" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
  !! end
  
  !! test
@@@ -20201,10 -19135,6 +20201,10 @@@ New wiki paragrap
  <p><b>Bold paragraph
  </p><p>New wiki paragraph</b>
  </p>
 +!! html/php+tidy
 +<p><b>Bold paragraph
 +</b></p><p><b>New wiki paragraph
 +</b></p>
  !! html/parsoid
  <p><b>Bold paragraph</b>
  </p><p>New wiki paragraph
  !! test
  Handling of &#x0A; in URLs
  !! wikitext
 -*irc://&#x0A;a
 +*irc://&#x0A;a
  !! html/php
 -<ul><li><ul><li> <a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul></li></ul>
 +<ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
  
  !! html/parsoid
 -<ul><li><ul><li> <a rel="mw:ExtLink" class="external free" href="irc://%0Aa" data-parsoid='{"stx":"url","a":{"href":"irc://%0Aa"},"sa":{"href":"irc://&amp;#x0A;a"}}'>irc://%0Aa</a></li></ul></li></ul>
 +<ul><li><a rel="mw:ExtLink" class="external free" href="irc://%0Aa" data-parsoid='{"stx":"url","a":{"href":"irc://%0Aa"},"sa":{"href":"irc://&amp;#x0A;a"}}'>irc://%0Aa</a></li></ul>
  !! end
  
  !! test
  Handling of %0A in URLs
  !! wikitext
 -*irc://%0Aa
 +*irc://%0Aa
  !! html/php
 -<ul><li><ul><li> <a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul></li></ul>
 +<ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
  
  !! html/parsoid
 -<ul><li><ul><li> <a rel="mw:ExtLink" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul></li></ul>
 +<ul><li><a rel="mw:ExtLink" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul>
  !! end
  
  # The PHP parser strips the empty tags out for giggles; parsoid doesn't.
@@@ -21154,7 -20084,7 +21154,7 @@@ parsoid=wt2htm
  '''''
  !! html/php
  !! html/parsoid
 -<b><i></i></b>
 +<p><b><i></i></b></p>
  !! end
  
  # same html as previous, but wikitext adjusted to match parsoid html2wt
@@@ -21212,51 -20142,51 +21212,51 @@@ Say the magic wor
  !! options
  title=[[Parser test]]
  !! wikitext
 -* {{PAGENAME}}
 -* {{PAGENAMEE}}
 -* {{FULLPAGENAME}}
 -* {{FULLPAGENAMEE}}
 -* {{BASEPAGENAME}}
 -* {{BASEPAGENAMEE}}
 -* {{SUBPAGENAME}}
 -* {{SUBPAGENAMEE}}
 -* {{ROOTPAGENAME}}
 -* {{ROOTPAGENAMEE}}
 -* {{TALKPAGENAME}}
 -* {{TALKPAGENAMEE}}
 -* {{SUBJECTPAGENAME}}
 -* {{SUBJECTPAGENAMEE}}
 -* {{NAMESPACEE}}
 -* {{NAMESPACE}}
 -* {{NAMESPACENUMBER}}
 -* {{TALKSPACE}}
 -* {{TALKSPACEE}}
 -* {{SUBJECTSPACE}}
 -* {{SUBJECTSPACEE}}
 -* {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}}
 -!! html
 -<ul><li> Parser test</li>
 -<li> Parser_test</li>
 -<li> Parser test</li>
 -<li> Parser_test</li>
 -<li> Parser test</li>
 -<li> Parser_test</li>
 -<li> Parser test</li>
 -<li> Parser_test</li>
 -<li> Parser test</li>
 -<li> Parser_test</li>
 -<li> Talk:Parser test</li>
 -<li> Talk:Parser_test</li>
 -<li> Parser test</li>
 -<li> Parser_test</li>
 -<li> </li>
 -<li> </li>
 -<li> 0</li>
 -<li> Talk</li>
 -<li> Talk</li>
 -<li> </li>
 -<li> </li>
 -<li> <a href="/index.php?title=Template:Dynamic&amp;action=edit&amp;redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a></li></ul>
 +*{{PAGENAME}}
 +*{{PAGENAMEE}}
 +*{{FULLPAGENAME}}
 +*{{FULLPAGENAMEE}}
 +*{{BASEPAGENAME}}
 +*{{BASEPAGENAMEE}}
 +*{{SUBPAGENAME}}
 +*{{SUBPAGENAMEE}}
 +*{{ROOTPAGENAME}}
 +*{{ROOTPAGENAMEE}}
 +*{{TALKPAGENAME}}
 +*{{TALKPAGENAMEE}}
 +*{{SUBJECTPAGENAME}}
 +*{{SUBJECTPAGENAMEE}}
 +*{{NAMESPACEE}}
 +*{{NAMESPACE}}
 +*{{NAMESPACENUMBER}}
 +*{{TALKSPACE}}
 +*{{TALKSPACEE}}
 +*{{SUBJECTSPACE}}
 +*{{SUBJECTSPACEE}}
 +*{{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}}
 +!! html
 +<ul><li>Parser test</li>
 +<li>Parser_test</li>
 +<li>Parser test</li>
 +<li>Parser_test</li>
 +<li>Parser test</li>
 +<li>Parser_test</li>
 +<li>Parser test</li>
 +<li>Parser_test</li>
 +<li>Parser test</li>
 +<li>Parser_test</li>
 +<li>Talk:Parser test</li>
 +<li>Talk:Parser_test</li>
 +<li>Parser test</li>
 +<li>Parser_test</li>
 +<li></li>
 +<li></li>
 +<li>0</li>
 +<li>Talk</li>
 +<li>Talk</li>
 +<li></li>
 +<li></li>
 +<li><a href="/index.php?title=Template:Dynamic&amp;action=edit&amp;redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a></li></ul>
  
  !! end
  ### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included.
@@@ -21557,7 -20487,6 +21557,6 @@@ image:foobar.jpg|link=Main Page#section
  </ul>
  !! end
  
- ## Whoops, Parsoid shouldn't be parsing templates in the attribute caption!
  !! test
  Gallery with template inside caption
  !! options
@@@ -21570,7 -20499,7 +21569,7 @@@ File:Foobar.jpg|{{echo|ho}
  </gallery>
  !! html/php
  <ul class="gallery mw-gallery-traditional">
-       <li class='gallerycaption'>{{echo|hi}}</li>
+       <li class='gallerycaption'>hi</li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
                        <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
  </ul>
  !! end
  
+ !! test
+ Gallery with wikitext inside gallery caption
+ !! wikitext
+ <gallery caption="# List item
+ Text '''bold''' [[link]] {{ns:-1}}
+ [[File:Foobar.jpg|thumb|File in gallery caption]]">
+ File:Foobar.jpg|Image caption
+ </gallery>
+ !! html/php
+ <ul class="gallery mw-gallery-traditional">
+       <li class='gallerycaption'># List item Text <b>bold</b> <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> Special <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>File in gallery caption</div></div></div></li>
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+ <p>Image caption
+ </p>
+                       </div>
+               </div></li>
+ </ul>
+ !! end
  !! test
  Gallery with wikitext inside caption
  !! options
@@@ -21923,25 -20876,6 +21946,25 @@@ File:Foobar.jp
  </ul>
  !! end
  
 +!! test
 +Serialize gallery image captions on a line
 +!! options
 +parsoid={
 +  "modes": ["html2wt"],
 +  "nativeGallery": true
 +}
 +!! html/parsoid
 +<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
 +<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext"><p>hi</p><p>ho</p></div></li>
 +<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px;"><figure-inline typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div><div class="gallerytext">hi<br />ho</div></li>
 +</ul>
 +!! wikitext
 +<gallery>
 +File:Foobar.jpg| hi  ho 
 +File:Foobar.jpg|hi<br />ho
 +</gallery>
 +!! end
 +
  !! test
  HTML Hex character encoding (spells the word "JavaScript")
  !! options
@@@ -21991,20 -20925,20 +22014,20 @@@ Illegal character references (T106578
  ; Surrogate: &#xD83D;&#xDCA9;
  ; This is an okay astral character: &#x1F4A9;
  !! html+tidy
 -<dl><dt> Null</dt>
 -<dd> &amp;#00;</dd>
 -<dt> FF</dt>
 -<dd> &amp;#xC;</dd>
 -<dt> CR</dt>
 -<dd> &amp;#xD;</dd>
 -<dt> Control (low)</dt>
 -<dd> &amp;#8;</dd>
 -<dt> Control (high)</dt>
 -<dd> &amp;#x7F; &amp;#x9F;</dd>
 -<dt> Surrogate</dt>
 -<dd> &amp;#xD83D;&amp;#xDCA9;</dd>
 -<dt> This is an okay astral character</dt>
 -<dd> &#x1f4a9;</dd></dl>
 +<dl><dt>Null</dt>
 +<dd>&amp;#00;</dd>
 +<dt>FF</dt>
 +<dd>&amp;#xC;</dd>
 +<dt>CR</dt>
 +<dd>&amp;#xD;</dd>
 +<dt>Control (low)</dt>
 +<dd>&amp;#8;</dd>
 +<dt>Control (high)</dt>
 +<dd>&amp;#x7F; &amp;#x9F;</dd>
 +<dt>Surrogate</dt>
 +<dd>&amp;#xD83D;&amp;#xDCA9;</dd>
 +<dt>This is an okay astral character</dt>
 +<dd>&#x1f4a9;</dd></dl>
  !! end
  
  !! test
@@@ -22101,22 -21035,18 +22124,22 @@@ T24905: <abbr> followed by ISBN followe
  Double RFC
  !! wikitext
  RFC RFC 1234
 -!! html
 +!! html/php
  <p>RFC <a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc1234">RFC 1234</a>
  </p>
 +!! html/parsoid
 +<p>RFC <a href="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external mw-magiclink">RFC 1234</a></p>
  !! end
  
  !! test
  Double RFC with a wiki link
  !! wikitext
  RFC [[RFC 1234]]
 -!! html
 +!! html/php
  <p>RFC <a href="/index.php?title=RFC_1234&amp;action=edit&amp;redlink=1" class="new" title="RFC 1234 (page does not exist)">RFC 1234</a>
  </p>
 +!! html/parsoid
 +<p>RFC <a rel="mw:WikiLink" href="./RFC_1234" title="RFC 1234">RFC 1234</a></p>
  !! end
  
  !! test
@@@ -22127,7 -21057,7 +22150,7 @@@ RFC   983&#x20;98
  <p><a class="external mw-magiclink-rfc" rel="nofollow" href="https://tools.ietf.org/html/rfc983">RFC 983</a>&#x20;987
  </p>
  !! html/parsoid
 -<p><a href="https://tools.ietf.org/html/rfc983" rel="mw:ExtLink" class="external text" data-parsoid='{"stx":"magiclink"}'>RFC   983</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>987</p>
 +<p><a href="https://tools.ietf.org/html/rfc983" rel="mw:ExtLink" class="external mw-magiclink" data-parsoid='{"stx":"magiclink"}'>RFC   983</a><span typeof="mw:Entity" data-parsoid='{"src":"&amp;#x20;","srcContent":" "}'> </span>987</p>
  !! end
  
  !! test
@@@ -22261,8 -21191,6 +22284,8 @@@ wgRawHtml=
  !! html/php
  <p><script>alert(1);</script>
  </p>
 +!! html/parsoid
 +<p><script typeof="mw:Extension/html" about="#mwt3" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;script>alert(1);&lt;/script>"}}'>alert(1);</script></p>
  !! end
  
  !! test
@@@ -22374,21 -21302,21 +22397,21 @@@ parsoid=wt2htm
  !! test
  Definition list code coverage
  !! wikitext
 -; title   : def
 -; title : def
 -;title: def
 +;title   :def
 +;title :def
 +;title:def
  !! html/php
 -<dl><dt> title  &#160;</dt>
 -<dd> def</dd>
 -<dt> title&#160;</dt>
 -<dd> def</dd>
 +<dl><dt>title</dt>
 +<dd>def</dd>
 +<dt>title</dt>
 +<dd>def</dd>
  <dt>title</dt>
 -<dd> def</dd></dl>
 +<dd>def</dd></dl>
  
  !! html/parsoid
 -<dl><dt> title  <span typeof="mw:Placeholder"> </span></dt><dd> def</dd>
 -<dt> title<span typeof="mw:Placeholder"> </span></dt><dd> def</dd>
 -<dt>title</dt><dd> def</dd></dl>
 +<dl><dt>title   </dt><dd>def</dd>
 +<dt>title </dt><dd>def</dd>
 +<dt>title</dt><dd>def</dd></dl>
  !! end
  
  !! test
@@@ -22466,7 -21394,7 +22489,7 @@@ Out-of-order TOC heading level
  =====5=====
  ==2==
  !! html
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#2"><span class="tocnumber">1</span> <span class="toctext">2</span></a>
  <ul>
@@@ -22632,7 -21560,7 +22655,7 @@@ anchorencode encodes like the TOC gener
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
 -=== _ +:.3A%3A _ &&amp;]] x ===
 +===_ +:.3A%3A _ &&amp;]] x===
  {{anchorencode: _ +:.3A%3A _ &&amp;]] x}}
  __NOEDITSECTION__
  !! html/php
  <p>+:.3A%3A_&amp;&amp;&#93;&#93;_x
  </p>
  !! html/parsoid
 -<h3 id="+:.3A%3A_&amp;&amp;]]_x"><span id=".2B:.3A.253A_.26.26.5D.5D_x" typeof="mw:FallbackId"></span> _ +:.3A%3A _ &amp;<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;","dsr":[18,23,null,null]}'>&amp;</span>]] x </h3>
 +<h3 id="+:.3A%3A_&amp;&amp;]]_x"><span id=".2B:.3A.253A_.26.26.5D.5D_x" typeof="mw:FallbackId"></span>_ +:.3A%3A _ &amp;<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;","dsr":[18,23,null,null]}'>&amp;</span>]] x</h3>
  <p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"anchorencode: _ +:.3A%3A _ &amp;&amp;amp;]] x","function":"anchorencode"},"params":{},"i":0}}]}'>+:.3A%3A_&amp;&amp;<span typeof="mw:Entity">]</span><span typeof="mw:Entity">]</span>_x</p>
  <meta property="mw:PageProp/noeditsection"/>
  !! end
@@@ -22650,7 -21578,7 +22673,7 @@@ anchorencode encodes like the TOC gener
  !! config
  wgFragmentMode=[ 'legacy' ]
  !! wikitext
 -=== _ +:.3A%3A&&amp;]] ===
 +===_ +:.3A%3A&&amp;]]===
  {{anchorencode: _ +:.3A%3A&&amp;]] }}
  __NOEDITSECTION__
  !! html/php
@@@ -22934,21 -21862,21 +22957,21 @@@ wgFragmentMode=[ 'html5', 'legacy' 
  !! options
  language=sr variant=sr-ec
  !! wikitext
 -== -{Naslov}- ==
 +==-{Naslov}-==
  
  Note that even an unprotected headline ID is not affected by language
  conversion:
  
 -== Latinski ==
 +==Latinski==
  !! html/php
 -<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Уреди одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<h2><span id="-.7BNaslov.7D-"></span><span class="mw-headline" id="-{Naslov}-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Уредите одељак „Naslov”">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
  <p>Ноте тхат евен ан унпротецтед хеадлине ИД ис нот аффецтед бy лангуаге
  цонверсион:
  </p>
 -<h2><span class="mw-headline" id="Latinski">Латински</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Уреди одељак „Латински“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<h2><span class="mw-headline" id="Latinski">Латински</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Уредите одељак „Латински”">уреди</a><span class="mw-editsection-bracket">]</span></span></h2>
  
  !! html/parsoid
 -<h2 id="-{Naslov}-"><span id="-.7BNaslov.7D-" typeof="mw:FallbackId"></span> <span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"Naslov"}}'></span> </h2>
 +<h2 id="-{Naslov}-"><span id="-.7BNaslov.7D-" typeof="mw:FallbackId"></span><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"Naslov"}}'></span></h2>
  
  <p>Note that even an unprotected headline ID is not affected by language
  conversion:</p>
@@@ -23510,11 -22438,11 +23533,11 @@@ language=zh variant=zh-c
  <span>ad
  </span></div></span></div></span>
  !! html/parsoid
 -<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</span></p><div typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[10,16,5,0]}&#39;>c&lt;/div>"}}'></div><p>d</p>
 +<span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<div typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[10,16,5,0]}&apos;>c&lt;/div>"}}'></div>d
  
 -<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a</span></p><div typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["zh","zh-hans","zh-hant"],"t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[50,56,5,0]}&#39;>c&lt;/div>"}}'></div><p>d</p>
 +<span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<div typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["zh","zh-hans","zh-hant"],"t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[50,56,5,0]}&apos;>c&lt;/div>"}}'></div>d
  
 -<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"0","l":"zh-cn","t":"x&lt;span data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[82,89,6,0]}&#39;>y&lt;/span>"},{"f":"0","l":"zh-tw","t":"b&lt;div data-parsoid=&#39;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[100,106,5,0]}&#39;>c&lt;/div>"}]}'/>d</span></p>
 +<p><span data-parsoid='{"stx":"html","autoInsertedEnd":true}'>a<meta typeof="mw:LanguageVariant" data-mw-variant='{"add":true,"oneway":[{"f":"0","l":"zh-cn","t":"x&lt;span data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[82,89,6,0]}&apos;>y&lt;/span>"},{"f":"0","l":"zh-tw","t":"b&lt;div data-parsoid=&apos;{\"stx\":\"html\",\"autoInsertedEnd\":true,\"dsr\":[100,106,5,0]}&apos;>c&lt;/div>"}]}'/>d</span></p></span></span>
  !! end
  
  !! test
@@@ -23627,8 -22555,8 +23650,8 @@@ gopher://www.google.co
  !! html/php
  <p><a rel="nofollow" class="external free" href="http://www.google.com">http://www.google.com</a>
  <a rel="nofollow" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
 -<a rel="nofollow" class="external free" href="http://www.google.com">http://www.google.com</a>
 -<a rel="nofollow" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
 +<a rel="nofollow" class="external text" href="http://www.google.com">http://www.google.com</a>
 +<a rel="nofollow" class="external text" href="gopher://www.google.com">gopher://www.google.com</a>
  <a rel="nofollow" class="external text" href="https://www.google.com">irc://www.google.com</a>
  <a rel="nofollow" class="external text" href="ftp://www.google.com">www.гоогле.цом/фтп://дир</a>
  <a rel="nofollow" class="external text" href="//www.google.com">www.гоогле.цом</a>
  !! html/parsoid
  <p><a rel="mw:ExtLink" class="external free" href="http://www.google.com">http://www.google.com</a>
  <a rel="mw:ExtLink" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
 -<a rel="mw:ExtLink" class="external free" href="http://www.google.com">http://www.google.com</a>
 -<a rel="mw:ExtLink" class="external free" href="gopher://www.google.com">gopher://www.google.com</a>
 +<a rel="mw:ExtLink" class="external text" href="http://www.google.com">http://www.google.com</a>
 +<a rel="mw:ExtLink" class="external text" href="gopher://www.google.com">gopher://www.google.com</a>
  <a rel="mw:ExtLink" class="external text" href="https://www.google.com">irc://www.google.com</a>
  <a rel="mw:ExtLink" class="external text" href="ftp://www.google.com">www.google.com/ftp://dir</a>
  <a rel="mw:ExtLink" class="external text" href="//www.google.com">www.google.com</a></p>
@@@ -23713,7 -22641,7 +23736,7 @@@ language=s
  !! wikitext
  [[Датотека:Foobar.jpg|thumb|-{R|caption:}-]]
  !! html/php
 -<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="internal" title="Повећај"></a></div>caption:</div></div></div>
 +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/%D0%94%D0%B0%D1%82%D0%BE%D1%82%D0%B5%D0%BA%D0%B0:Foobar.jpg" class="internal" title="Повећајте"></a></div>caption:</div></div></div>
  
  !! html/parsoid
  <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"}]}'><a href="./Датотека:Foobar.jpg"><img resource="./Датотека:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><span typeof="mw:LanguageVariant" data-mw-variant='{"disabled":{"t":"caption:"}}' data-parsoid='{"fl":["R"]}'></span></figcaption></figure>
@@@ -23798,8 -22726,10 +23821,8 @@@ language=zh variant=zh-c
  <dt>-{zh-cn:AAA</dt></b></dl><p><b>
  </b></p>
  !! html/parsoid
 -<dl><dt data-parsoid='{"dsr":[0,11,1,0]}'><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'>foo:bar</b></dt><b data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
 -<dt data-parsoid='{"dsr":[12,20,1,0]}'>-{zh-cn</dt>
 -<dd data-parsoid='{"stx":"row","dsr":[20,24,1,0]}'>AAA</dd>
 -</b></dl>
 +<dl><dt data-parsoid='{}'><b data-parsoid='{"stx":"html","autoInsertedEnd":true}'>foo:bar</b></dt><b data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
 +<dt data-parsoid='{}'>-{zh-cn</dt><dd data-parsoid='{"stx":"row"}'>AAA</dd></b></dl>
  !! end
  
  !! test
@@@ -23833,7 -22763,7 +23856,7 @@@ parsoid=wt2html,wt2wt,html2htm
  <table>
  
  <tr>
 -<td> B
 +<td>B
  </td></tr></table>
  
  !! html/parsoid
@@@ -23964,20 -22894,20 +23987,20 @@@ language=s
  !! test
  T2529: Uncovered bullet
  !! wikitext
 -* Foo {{bullet}}
 +*Foo {{bullet}}
  !! html
 -<ul><li> Foo </li>
 -<li> Bar</li></ul>
 +<ul><li>Foo</li>
 +<li>Bar</li></ul>
  
  !! end
  
  !! test
  T2529: Uncovered bullet in a deeply nested list
  !! wikitext
 -******* Foo {{bullet}}
 +*******Foo {{bullet}}
  !! html
 -<ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li> Foo </li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li>
 -<li> Bar</li></ul>
 +<ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li>Foo</li></ul></li></ul></li></ul></li></ul></li></ul></li></ul></li>
 +<li>Bar</li></ul>
  
  !! end
  
  </p>
  <table>
  <tr>
 -<td> 1 </td>
 -<td> 2
 +<td>1</td>
 +<td>2
  </td></tr>
  <tr>
 -<td> 3 </td>
 -<td> 4
 +<td>3</td>
 +<td>4
  </td></tr></table>
  <p>y
  </p>
  !! test
  T2529: Uncovered bullet in parser function result
  !! wikitext
 -* Foo {{lc:{{bullet}} }}
 +*Foo {{lc:{{bullet}} }}
  !! html
 -<ul><li> Foo </li>
 -<li> bar</li></ul>
 +<ul><li>Foo</li>
 +<li>bar</li></ul>
  
  !! end
  
@@@ -24164,6 -23094,7 +24187,6 @@@ Line tw
  !! end
  
  # doBlockLevels screws up this output and Remex cleans up as much as it can.
 -# Parsoid seems to do a better job here since its p-wrapper is probably smarter.
  !! test
  Nesting tags, paragraphs on lines which begin with <div>
  !! wikitext
@@@ -24174,8 -23105,10 +24197,8 @@@ B</strong
  </strong></p><strong></strong><p><strong>B</strong>
  </p>
  !! html/parsoid
 -<div></div>
 -<p><strong>A
 -B</strong>
 -</p>
 +<div data-parsoid='{"stx":"html"}'></div><p><strong data-parsoid='{"stx":"html","autoInsertedEnd":true}'>A</strong></p>
 +<p><strong data-parsoid='{"stx":"html","autoInsertedStart":true}'>B</strong></p>
  !! end
  
  # T8200: <blockquote> should behave like <div> with respect to line breaks
@@@ -24251,12 -23184,7 +24274,12 @@@ Line tw
  
  !! end
  
 -# FIXME: Why does/should the blockquote+div combo suppress p-wrapping here?
 +## This is a corner case interaction between the paragraph wrapping in the
 +## php parser's BlockLevelPass and Remex.  `doBlockLevels` has a notion of
 +## some tags which close paragraphs (and thus prevent wrapping on their line),
 +## of which "div" is one, but do p-wrapping inside them.  These are referred
 +## to as "never suppressing".  Remex, for its part, doesn't traverse into
 +## "div"s to p-wrap.  Hence, we only get this partial wrapping.
  !! test
  Paragraphs inside blockquotes/divs (no extra line breaks)
  !! wikitext
@@@ -24460,7 -23388,7 +24483,7 @@@ comment title=[[Main Page]
  !! wikitext
  /* External links */ removed bogus entries
  !! html/php
 -<a href="/wiki/Main_Page#External_links" title="Main Page">→</a>‎<span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span>
 +<a href="/wiki/Main_Page#External_links" title="Main Page">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
  !!end
  
  !! test
@@@ -24470,7 -23398,7 +24493,7 @@@ comment title=[[Main Page]
  !! wikitext
  pre-comment text /* External links */ removed bogus entries
  !! html/php
 -pre-comment text <a href="/wiki/Main_Page#External_links" title="Main Page">→</a>‎<span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span>
 +pre-comment text <a href="/wiki/Main_Page#External_links" title="Main Page">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
  !!end
  
  !! test
@@@ -24480,7 -23408,7 +24503,7 @@@ comment local title=[[Main Page]
  !! wikitext
  /* External links */ removed bogus entries
  !! html/php
 -<a href="#External_links">→</a>‎<span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span>
 +<a href="#External_links">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
  !!end
  
  !! test
@@@ -24591,7 -23519,7 +24614,7 @@@ title=[[Main Page]
  !! wikitext
  /* __hello__world__ */
  !! html/php
 -<a href="/wiki/Main_Page#hello_world" title="Main Page">→</a>‎<span dir="auto"><span class="autocomment">__hello__world__</span></span>
 +<a href="/wiki/Main_Page#hello_world" title="Main Page">→__hello__world__</a>‎
  !! end
  
  !! test
@@@ -24614,7 -23542,7 +24637,7 @@@ commen
  Bad images - basic functionality
  !! wikitext
  [[File:Bad.jpg]]
 -!! DISABLED/html/php
 +!! html/php+disabled
  !! html/parsoid
  <p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"bad-image","message":"This image is blacklisted in this context."}]}'><a href="./File:Bad.jpg"><img resource="./File:Bad.jpg" height="220" width="220"/></a></span></p>
  !! end
@@@ -24625,7 -23553,7 +24648,7 @@@ Bad images - T18039: text after bad ima
  Foo bar
  [[File:Bad.jpg]]
  Bar foo
 -!! DISABLED/html/php
 +!! html/php+disabled
  <p>Foo bar
  </p><p>Bar foo
  </p>
@@@ -24803,13 -23731,13 +24826,13 @@@ showindicator
  <indicator name="02">[[Main Page]]</indicator>
  <indicator name="03">[[File:Foobar.jpg|25px|link=]]</indicator>
  <indicator name="04">[[File:Foobar.jpg|25px]]</indicator>
 -<indicator name="05">* foo
 -* bar</indicator>
 +<indicator name="05">*foo
 +*bar</indicator>
  <indicator name="06"><nowiki>foo</nowiki></indicator>
  <indicator name="07"> Preformatted</indicator>
  <indicator name="08"><div>Broken tag</indicator>
  <indicator name="09">{| class=wikitable
 -| cell
 +|cell
  |}</indicator>
  <indicator name="10">Two
  
@@@ -24819,8 -23747,8 +24842,8 @@@ paragraphs</indicator
  02=<a href="/wiki/Main_Page" title="Main Page">Main Page</a>
  03=<img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/25px-Foobar.jpg" width="25" height="3" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/38px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg 2x" />
  04=<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/25px-Foobar.jpg" width="25" height="3" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/38px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg 2x" /></a>
 -05=<ul><li> foo</li>
 -<li> bar</li></ul>
 +05=<ul><li>foo</li>
 +<li>bar</li></ul>
  
  06=foo
  07=<pre>Preformatted
  
  09=<table class="wikitable">
  <tr>
 -<td> cell
 +<td>cell
  </td></tr></table>
  
  10=<p>Two
@@@ -24894,7 -23822,7 +24917,7 @@@ Play a bit with r67090 and T515
  <div style="width:50% !important">&#160;</div>
  <div style="width:50% !important">&#160;</div>
  <div style="width:50% !important">&#160;</div>
 -<div style="border&#160;: solid;">&#160;</div>
 +<div style="border&#32;: solid;">&#160;</div>
  
  !! html/parsoid
  <div style="width:50% !important" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
  
  !! end
  
 +!! test
 +French spaces in wikitext
 +!! wikitext
 +foo ! bar ? bat 50 % is less than 75 %.
 +
 +Hello : this ; is « something ‹ else › again »
 +!! html
 +<p>foo&#160;! bar&#160;? bat 50&#160;% is less than 75&#160;%.
 +</p><p>Hello&#160;: this&#160;; is «&#160;something ‹&#160;else&#160;› again&#160;»
 +</p>
 +!! end
 +
 +# It would be reasonable for Parsoid and PHP to differ here.
 +# The PHP behavior is arguably a bug.
 +!! test
 +Corner case: french spaces in definition list
 +!! wikitext
 +;foo : bar
 +!! html+tidy
 +<dl><dt>foo&#160;</dt>
 +<dd>bar</dd></dl>
 +!! end
 +
 +!! test
 +T5158: Test for French spaces in attributes
 +!! wikitext
 +<br style=" clear : both ; " />
 +!! html/php
 +<p><br style="clear&#32;: both&#32;;" />
 +</p>
 +!! end
 +
  !! test
  HTML5 data attributes
  !! wikitext
@@@ -25128,9 -24024,9 +25151,9 @@@ T28375: TOC with italic
  title=[[Main Page]]
  !! wikitext
  __TOC__
 -== ''Lost'' episodes ==
 +==''Lost'' episodes==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Lost_episodes"><span class="tocnumber">1</span> <span class="toctext"><i>Lost</i> episodes</span></a></li>
  </ul>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="Lost_episodes" data-parsoid='{}'> <i>Lost</i> episodes </h2>
 +<h2 id="Lost_episodes" data-parsoid='{}'><i>Lost</i> episodes</h2>
  !! end
  
  !! test
@@@ -25149,9 -24045,9 +25172,9 @@@ T28375: TOC with bol
  title=[[Main Page]]
  !! wikitext
  __TOC__
 -== '''should be bold''' then normal text ==
 +=='''should be bold''' then normal text==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#should_be_bold_then_normal_text"><span class="tocnumber">1</span> <span class="toctext"><b>should be bold</b> then normal text</span></a></li>
  </ul>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="should_be_bold_then_normal_text" data-parsoid='{}'> <b>should be bold</b> then normal text </h2>
 +<h2 id="should_be_bold_then_normal_text" data-parsoid='{}'><b>should be bold</b> then normal text</h2>
  !! end
  
  !! test
@@@ -25170,9 -24066,9 +25193,9 @@@ T35845: Headings become cursive in TOC 
  title=[[Main Page]]
  !! wikitext
  __TOC__
 -== Image [[Image:foobar.jpg]] ==
 +==Image [[Image:foobar.jpg]]==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Image"><span class="tocnumber">1</span> <span class="toctext">Image</span></a></li>
  </ul>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="Image" data-parsoid='{}'> Image <figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure-inline> </h2>
 +<h2 id="Image" data-parsoid='{}'>Image <figure-inline class="mw-default-size" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"Image:foobar.jpg"}}'/></a></figure-inline></h2>
  !! end
  
  !! test
@@@ -25191,9 -24087,9 +25214,9 @@@ T35845 (2): Headings become bold in TO
  title=[[Main Page]]
  !! wikitext
  __TOC__
 -== <blockquote>Quote</blockquote> ==
 +==<blockquote>Quote</blockquote>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
  </ul>
  <h2><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  
  !! html/php+tidy
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
  </ul>
  <h2><span class="mw-headline" id="Quote"><blockquote><p>Quote</p></blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="Quote" data-parsoid='{}'> <blockquote>Quote</blockquote> </h2>
 +<h2 id="Quote" data-parsoid='{}'><blockquote><p>Quote</p></blockquote></h2>
  !! end
  
  !! test
@@@ -25222,11 -24118,11 +25245,11 @@@ wgFragmentMode=[ 'html5', 'legacy' 
  title=[[Main Page]]
  !! wikitext
  __TOC__
 -== Proof: 2 < 3 ==
 +==Proof: 2 < 3==
  <small>Hanc marginis exiguitas non caperet.</small>
  QED
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Proof:_2_&lt;_3"><span class="tocnumber">1</span> <span class="toctext">Proof: 2 &lt; 3</span></a></li>
  </ul>
  </p>
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="Proof:_2_&lt;_3" data-parsoid='{}'><span id="Proof:_2_.3C_3" typeof="mw:FallbackId"></span> Proof: 2 &lt; 3 </h2>
 +<h2 id="Proof:_2_&lt;_3" data-parsoid='{}'><span id="Proof:_2_.3C_3" typeof="mw:FallbackId"></span>Proof: 2 &lt; 3</h2>
  <p><small>Hanc marginis exiguitas non caperet.</small>
  QED</p>
  !! end
  Multiple tags in TOC
  !! wikitext
  __TOC__
 -== <i>Foo</i> <b>Bar</b> ==
 +==<i>Foo</i> <b>Bar</b>==
  
 -== <i>Foo</i> <blockquote>Bar</blockquote> ==
 +==<i>Foo</i> <blockquote>Bar</blockquote>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
  <h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  
  !! html/php+tidy
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none" /><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
  <h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote><p>Bar</p></blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="Foo_Bar" data-parsoid='{}'> <i data-parsoid='{"stx":"html"}'>Foo</i> <b data-parsoid='{"stx":"html"}'>Bar</b> </h2>
 +<h2 id="Foo_Bar" data-parsoid='{}'><i data-parsoid='{"stx":"html"}'>Foo</i> <b data-parsoid='{"stx":"html"}'>Bar</b></h2>
  
 -<h2 id="Foo_Bar_2" data-parsoid='{}'> <i data-parsoid='{"stx":"html"}'>Foo</i> <blockquote>Bar</blockquote> </h2>
 +<h2 id="Foo_Bar_2" data-parsoid='{}'><i data-parsoid='{"stx":"html"}'>Foo</i> <blockquote><p>Bar</p></blockquote></h2>
  !! end
  
  # Don't expect Parsoid to roundtrip this until the php parser comes closer to
@@@ -25286,11 -24182,11 +25309,11 @@@ Tags with parameters in TO
  parsoid=wt2html
  !! wikitext
  __TOC__
 -== <sup class="in-h2">Hello</sup> ==
 +==<sup class="in-h2">Hello</sup>==
  
 -== <sup class="a > b">Evilbye</sup> ==
 +==<sup class="a > b">Evilbye</sup>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Hello"><span class="tocnumber">1</span> <span class="toctext"><sup>Hello</sup></span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#b.22.3EEvilbye"><span class="tocnumber">2</span> <span class="toctext"><sup> b"&gt;Evilbye</sup></span></a></li>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" />
 -<h2 id="Hello"> <sup class="in-h2" data-parsoid='{"stx":"html"}'>Hello</sup> </h2>
 +<h2 id="Hello"><sup class="in-h2" data-parsoid='{"stx":"html"}'>Hello</sup></h2>
  
 -<h2 id='b">Evilbye'><span id="b.22.3EEvilbye" typeof="mw:FallbackId"></span> <sup class="a " data-parsoid='{"stx":"html"}'> b">Evilbye</sup> </h2>
 +<h2 id='b">Evilbye'><span id="b.22.3EEvilbye" typeof="mw:FallbackId"></span><sup class="a " data-parsoid='{"stx":"html"}'> b">Evilbye</sup></h2>
  !! end
  
  !! test
  span tags with directionality in TOC
  !! wikitext
  __TOC__
 -== <span dir="ltr">C++</span> ==
 +==<span dir="ltr">C++</span>==
  
 -== <span dir="rtl">זבנג!</span> ==
 +==<span dir="rtl">זבנג!</span>==
  
 -== <span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span> ==
 +==<span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span>==
  
 -== <span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span> ==
 +==<span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span>==
  
 -== <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> ==
 +==<span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#C.2B.2B"><span class="tocnumber">1</span> <span class="toctext"><span dir="ltr">C++</span></span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#.D7.96.D7.91.D7.A0.D7.92.21"><span class="tocnumber">2</span> <span class="toctext"><span dir="rtl">זבנג!</span></span></a></li>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="C++" data-parsoid='{}'><span id="C.2B.2B" typeof="mw:FallbackId"></span> <span dir="ltr">C++</span> </h2>
 -<h2 id="זבנג!"><span id=".D7.96.D7.91.D7.A0.D7.92.21" typeof="mw:FallbackId"></span> <span dir="rtl">זבנג!</span> </h2>
 -<h2 id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span> </h2>
 -<h2 id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span> </h2>
 -<h2 id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"> <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> </h2>
 +<h2 id="C++" data-parsoid='{}'><span id="C.2B.2B" typeof="mw:FallbackId"></span><span dir="ltr">C++</span></h2>
 +<h2 id="זבנג!"><span id=".D7.96.D7.91.D7.A0.D7.92.21" typeof="mw:FallbackId"></span><span dir="rtl">זבנג!</span></h2>
 +<h2 id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span></h2>
 +<h2 id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span></h2>
 +<h2 id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span></h2>
  !! end
  
  !! test
  T74884: bdi element in ToC
  !! wikitext
  __TOC__
 -== <bdi>test</bdi> ==
 +==<bdi>test</bdi>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#test"><span class="tocnumber">1</span> <span class="toctext"><bdi>test</bdi></span></a></li>
  </ul>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="test" data-parsoid='{}'> <bdi>test</bdi> </h2>
 +<h2 id="test" data-parsoid='{}'><bdi>test</bdi></h2>
  !! end
  
  !! test
  T35715: s/strike element in ToC
  !! wikitext
  __TOC__
 -== <s>test</s> test <strike>test</strike> ==
 +==<s>test</s> test <strike>test</strike>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#test_test_test"><span class="tocnumber">1</span> <span class="toctext"><s>test</s> test <strike>test</strike></span></a></li>
  </ul>
  
  !! html/parsoid
  <meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="test_test_test" data-parsoid='{}'> <s>test</s> test <strike>test</strike> </h2>
 +<h2 id="test_test_test" data-parsoid='{}'><s>test</s> test <strike>test</strike></h2>
  !! end
  
  !! test
 -Empty <p> tag in TOC, removed by Sanitizer (T92892)
 +T198618: style element in ToC
 +!! options
 +styletag=1
  !! wikitext
  __TOC__
 -== x ==
 +==<style>.foo {}</style>Style<style>.bar {}</style>==
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
 -<li class="toclevel-1 tocsection-1"><a href="#x"><span class="tocnumber">1</span> <span class="toctext">x</span></a></li>
 +<li class="toclevel-1 tocsection-1"><a href="#Style"><span class="tocnumber">1</span> <span class="toctext">Style</span></a></li>
  </ul>
  </div>
  
 -<h2><span class="mw-headline" id="x">x</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: x">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<h2><span class="mw-headline" id="Style"><style>.foo {}</style>Style<style>.bar {}</style></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Style">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  
  !! html/parsoid
 -<meta property="mw:PageProp/toc" data-parsoid='{}'/>
 -<h2 id="x" data-parsoid='{}'> x </h2>
 +<meta property="mw:PageProp/toc" data-parsoid="{}"/>
 +<h2 id="Style" data-parsoid="{}"><style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo {}"}}'>.foo {}</style>Style<style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".bar {}"}}'>.bar {}</style></h2>
  !! end
  
 -!! article
 +!! test
 +T198618: script element in ToC
 +!! options
 +wgRawHtml=1
 +!! wikitext
 +__TOC__
 +==<html><script>alert(1);</script></html>Script<html><script>alert(1);</script></html>==
 +!! html/php
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
 +<ul>
 +<li class="toclevel-1 tocsection-1"><a href="#Script"><span class="tocnumber">1</span> <span class="toctext">Script</span></a></li>
 +</ul>
 +</div>
 +
 +<h2><span class="mw-headline" id="Script"><script>alert(1);</script>Script<script>alert(1);</script></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Script">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +
 +!! html/parsoid
 +<meta property="mw:PageProp/toc" data-parsoid='{}'/>
 +<h2 id="Script" data-parsoid='{}'><script typeof="mw:Extension/html" about="#mwt4" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;script>alert(1);&lt;/script>"}}'>alert(1);</script>Script<script typeof="mw:Extension/html" about="#mwt6" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;script>alert(1);&lt;/script>"}}'>alert(1);</script></h2>
 +!! end
 +
 +!! test
 +Empty <p> tag in TOC, removed by Sanitizer (T92892)
 +!! wikitext
 +__TOC__
 +==x==
 +!! html/php
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
 +<ul>
 +<li class="toclevel-1 tocsection-1"><a href="#x"><span class="tocnumber">1</span> <span class="toctext">x</span></a></li>
 +</ul>
 +</div>
 +
 +<h2><span class="mw-headline" id="x">x</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: x">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +
 +!! html/parsoid
 +<meta property="mw:PageProp/toc" data-parsoid='{}'/>
 +<h2 id="x" data-parsoid='{}'>x</h2>
 +!! end
 +
 +!! article
  MediaWiki:T34057
  !! text
  == {{int:headline_sample}} ==
@@@ -25594,17 -24448,17 +25617,17 @@@ new support for bdi element (T33817
  Ignore pipe between table row attributes
  !! wikitext
  {|
 -| quux
 +|quux
  |- id=foo | style='color: red'
 -| bar
 +|bar
  |}
  !! html
  <table>
  <tr>
 -<td> quux
 +<td>quux
  </td></tr>
  <tr id="foo" style="color: red">
 -<td> bar
 +<td>bar
  </td></tr></table>
  
  !! end
  <span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"padright:","function":"padright"},"params":{"1":{"wt":"3"},"2":{"wt":"abcde"}},"i":0}}]}'>abc</span></p>
  !! end
  
 +!! test
 +Padleft and padright with non-numerical length (T180403)
 +!! wikitext
 +{{padleft:abcdef|junk}}
 +{{padright:abcdef|junk}}
 +!! html/php
 +<p>abcdef
 +abcdef
 +</p>
 +!! end
 +
  !!test
  Special parser function
  !! wikitext
@@@ -25721,11 -24564,11 +25744,11 @@@ Disable TO
  notoc
  !! wikitext
  Lead
 -== Section 1 ==
 -== Section 2 ==
 -== Section 3 ==
 -== Section 4 ==
 -== Section 5 ==
 +==Section 1==
 +==Section 2==
 +==Section 3==
 +==Section 4==
 +==Section 5==
  !! html
  <p>Lead
  </p>
  ###
  !!test
  1. SOL-sensitive wikitext tokens as template-args
 -!!options
 +!! options
  parsoid=wt2html,wt2wt
  !! wikitext
  {{echo|*a}}
  {{echo|#a}}
  {{echo|:a}}
 -!! html
 +!! html/php+tidy
 +<ul><li>a</li></ul>
 +<ol><li>a</li></ol>
 +<dl><dd>a</dd></dl>
 +!! html/parsoid
  <span about="#mwt1" typeof="mw:Transclusion">
  </span><ul about="#mwt1"><li>a</li>
  </ul>
  #### Parsoid-specific functionality tests
  #### -----------------------------------------------------------------
  
 -# T65642/T68749: Formatting elt fixup around images is cleaned up.
 +# T65642/T68749: Formatting elt fixup around images.
  # We know wt2wt will fail, but we expect selser to pass.
  # Due to the nature of our testing, wt2wt and selser tests will enter the
  # blacklist and we'll catch selser regressions based on changes to the
  # blacklist entries for selser tests.
  !! test
 -1. Bad treebuilder fixup of formatting elt is cleaned up
 +1. Treebuilder fixup of formatting elt
  !! options
  parsoid=wt2html,wt2wt
  !! wikitext
  [[Image:Foobar.jpg|right|Test]]
  </small>
  |}
 +!! html/php+tidy
 +<table>
 +<tbody><tr>
 +<td>
 +<p><small>
 +</small></p><small>
 +<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Test"><img alt="Test" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div>
 +</small><p><small></small>
 +</p>
 +</td></tr></tbody></table>
  !! html/parsoid
  <table>
  <tbody><tr><td>
 -<small>
 -<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Test</figcaption></figure>
 -</small>
 -</td></tr>
 +<p><small data-parsoid='{"stx":"html","autoInsertedEnd":true}'></small></p><small data-parsoid='{"stx":"html","autoInsertedEnd":true,"autoInsertedStart":true}'>
 +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>Test</figcaption></figure></small>
 +<p><small data-parsoid='{"stx":"html","autoInsertedStart":true}'></small></p></td></tr>
  </tbody></table>
  !! end
  
  !! test
 -2. Bad treebuilder fixup of formatting elt is cleaned up
 +2. Treebuilder fixup of formatting elt
  !! options
  parsoid=wt2html,wt2wt
  !! wikitext
  '''foo[[File:Foobar.jpg|thumb|caption]]bar'''
  
  <small>[[Image:Foobar.jpg|right|300px]]</small>
 +!! html/php+tidy
 +<p><b>foo</b></p><b><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div></b><p><b>bar</b>
 +</p><small><div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a></div></small>
  !! html/parsoid
 +<p><b>foo</b></p><b><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure></b><p><b>bar</b></p>
  
 -<p><b>foo</b></p>
 -<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><b>caption</b></figcaption></figure>
 -<p><b>bar</b></p>
  <small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small>
  !! end
  
  !! test
 -3. Bad treebuilder fixup of formatting elt is cleaned up
 +3. Treebuilder fixup of formatting elt
  !! options
  parsoid=wt2html,wt2wt
  !! wikitext
  <small>'''foo[[File:Foobar.jpg|thumb|caption]]bar'''</small>
 +!! html/php+tidy
 +<p><small><b>foo</b></small></p><small><b><div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>caption</div></div></div></b></small><p><small><b>bar</b></small>
 +</p>
  !! html/parsoid
 -<p><small><b>foo</b></small></p>
 -<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><small><b>caption</b></small></figcaption></figure>
 -<p><small><b>bar</b></small></p>
 +<p><small><b>foo</b></small></p><small><b><figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure></b></small><p><small><b>bar</b></small></p>
  !! end
  
  !! test
 -4. Bad treebuilder fixup of formatting elt is cleaned up: formatting tags around captionless images are ignored
 +4. Treebuilder fixup of formatting elt: formatting tags around captionless images
  !! options
  parsoid=wt2html,wt2wt
  !! wikitext
  '''<small>[[Image:Foobar.jpg|right|300px]]</small>'''
 +!! html/php+tidy
 +<b><small><div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" width="300" height="34" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/450px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/600px-Foobar.jpg 2x" /></a></div></small></b>
  !! html/parsoid
  <b><small><figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="34" width="300"/></a></figure></small></b>
  !! end
@@@ -25876,9 -24702,9 +25899,9 @@@ LST Sections: Newfangled approac
  <section begin="2011-05-16" />
  <section end="2014-04-10 (MW 1.23wmf22)" />
  !! html/parsoid
 -<p><span typeof="mw:Extension/section" about="#mwt4" data-mw='{"name":"section","attrs":{"begin":"2011-05-16"},"body":null}'>
 +<p><span typeof="mw:Extension/section" about="#mwt4" data-mw='{"name":"section","attrs":{"begin":"2011-05-16"}}'>
  </span>
 -<span typeof="mw:Extension/section" about="#mwt6" data-mw='{"name":"section","attrs":{"end":"2014-04-10 (MW 1.23wmf22)"},"body":null}'>
 +<span typeof="mw:Extension/section" about="#mwt6" data-mw='{"name":"section","attrs":{"end":"2014-04-10 (MW 1.23wmf22)"}}'>
  </span></p>
  !! end
  
@@@ -25909,10 -24735,9 +25932,10 @@@ Empty LI and TR nodes should be strippe
  !! test
  Empty LI and TR nodes should not be stripped from top-level content
  !! wikitext
 -* a
 +*a
  *
 -* b
 +*b
 +
  {|
  |-
  |-
  |}
  !! html/parsoid
  <ul>
 -<li> a</li>
 +<li>a</li>
  <li class='mw-empty-elt'></li>
 -<li> b</li>
 +<li>b</li>
  </ul>
  <table>
  <tbody>
@@@ -26839,92 -25664,6 +26862,92 @@@ parsoid=html2w
  
  !! end
  
 +!! test
 +Tables: 4e. Escape }
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<table>
 +<tr><td>}</td></tr>
 +<tr><td>x</td><td data-parsoid='{"stx":"row"}'>}</td></tr></table>
 +</table>
 +!! wikitext
 +{|
 +|<nowiki>}</nowiki>
 +|-
 +|x||}
 +|}
 +!! html/php
 +<table>
 +<tr>
 +<td>}
 +</td></tr>
 +<tr>
 +<td>x</td>
 +<td>}
 +</td></tr></table>
 +
 +!! end
 +
 +!! test
 +Tables: 5. Empty table cells should get whitespace to avoid need for nowikis
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<table><tr><td></td><td align="center" data-parsoid='{"stx":"row"}'></td><td data-parsoid='{"stx":"row"}'></td></tr></table>
 +
 +<table><tr><td></td><td align="center"></td><td></td></tr></table>
 +
 +<table><tr><td></td><td align="center" data-parsoid='{"stx":"row", "startTagSrc":"{{!}}{{!}}"}'></td><td data-parsoid='{"stx":"row"}'></td></tr></table>
 +
 +<table><tr><th></th><th align="center" data-parsoid='{"stx":"row"}'></th><th data-parsoid='{"stx":"row"}'></th></tr></table>
 +!! wikitext
 +{|
 +| || align="center" | ||
 +|}
 +
 +{|
 +|
 +| align="center" |
 +|
 +|}
 +
 +{|
 +| {{!}}{{!}} align="center" | ||
 +|}
 +
 +{|
 +! !! align="center" | !!
 +|}
 +!! html/php+tidy
 +<table>
 +<tbody><tr>
 +<td></td>
 +<td align="center"></td>
 +<td>
 +</td></tr></tbody></table>
 +<table>
 +<tbody><tr>
 +<td>
 +</td>
 +<td align="center">
 +</td>
 +<td>
 +</td></tr></tbody></table>
 +<table>
 +<tbody><tr>
 +<td></td>
 +<td align="center"></td>
 +<td>
 +</td></tr></tbody></table>
 +<table>
 +<tbody><tr>
 +<th></th>
 +<th align="center"></th>
 +<th>
 +</th></tr></tbody></table>
 +!! end
 +
  !! test
  T97430: Don't emit empty nowiki pairs around marker meta tags
  !! options
@@@ -26954,9 -25693,9 +26977,9 @@@ parsoid=html2w
  !! html/php
  <table>
  <tr>
 -<td> &lt;foo
 +<td>&lt;foo
  </td>
 -<td> bar&gt;
 +<td>bar&gt;
  </td></tr></table>
  
  !! end
@@@ -27454,6 -26193,8 +27477,6 @@@ bar <span><nowiki>[[foo]]</nowiki></spa
  !!end
  
  #### ----------------------- PRE --------------------------
 -#### 1. Leading whitespace in SOL context should be escaped
 -#### ------------------------------------------------------
  !! test
  1. Leading whitespace in SOL context should be escaped
  !! options
@@@ -27566,7 -26307,7 +27589,7 @@@ parsoid=html2w
   ==foo==
  !! end
  
 -!!test
 +!! test
  T95794: nowiki escaping should account for leading space at start-of-line in an indent-pre block
  !! options
  parsoid=html2wt
   * bar
  !! end
  
 +!! test
 +Whitespace scrubbing in SOL position should account for SOL-sensitive wikitext markup
 +!! options
 +parsoid = {
 +  "modes": ["html2wt"],
 +  "scrubWikitext": true
 +}
 +!! html/parsoid
 +<p> foo</p>
 +<p> %foo</p>
 +<p> *foo</p>
 +<p> #foo</p>
 +<p> =foo=</p>
 +<p><link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid="{}"> *foo</p>
 +<p> <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid="{}">*foo</p>
 +<p> <!--boo-->*foo</p>
 +<p><!--boo--> *foo</p>
 +<p><!--a--> <!--b--> <!--c--> <!--d--> <!--e--> foo</p>
 +<p><!--a--> <!--b--> <!--c--> <!--d--> <!--e--> *foo</p>
 +!! wikitext
 +foo
 +
 +%foo
 +
 +<nowiki/>*foo
 +
 +<nowiki/>#foo
 +
 +<nowiki/>=foo=
 +
 +[[Category:Foo]]
 +<nowiki/>*foo
 +
 + [[Category:Foo]]
 +<nowiki>*</nowiki>foo
 +
 +<nowiki/><!--boo-->*foo
 +
 +<!--boo--><nowiki/>*foo
 +
 +<!--a--><!--b--><!--c--><!--d--><!--e-->foo
 +
 +<!--a--><nowiki/><!--b--><!--c--><!--d--><!--e-->*foo
 +!! end
 +
  #### --------------- Behavior Switches --------------------
  
  !! test
@@@ -27740,18 -26436,6 +27763,18 @@@ parsoid=html2w
  baz<nowiki></ref></nowiki>
  !! end
  
 +!! test
 +Parsoid: newline inducing block nodes don't suppress <nowiki>
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 + a<h1>foo</h1>
 +!! wikitext
 +<nowiki> </nowiki>a
 +
 += foo =
 +!! end
 +
  #### --------------- Others ---------------
  !! test
  Escaping nowikis
@@@ -27901,12 -26585,12 +27924,12 @@@ parsoid=wt2html,html2htm
  Accept empty td cell attribute
  !! wikitext
  {|
 -| align="center" | foo ||  |
 +| align="center" |foo||  |
  |}
  !! html
  <table>
  <tr>
 -<td align="center"> foo </td>
 +<td align="center">foo</td>
  <td>
  </td></tr></table>
  
  Non-empty attributes in th-cells
  !! wikitext
  {|
 -! Foo !! style="color: red" | Bar
 +!Foo!! style="color: red" |Bar
  |}
  !! html
  <table>
  <tr>
 -<th> Foo </th>
 -<th style="color: red"> Bar
 +<th>Foo</th>
 +<th style="color: red">Bar
  </th></tr></table>
  
  !!end
  Accept empty attributes in th-cells
  !! wikitext
  {|
 -!| foo !!| bar
 +!|foo!!|bar
  |}
  !! html
  <table>
  <tr>
 -<th> foo </th>
 -<th> bar
 +<th>foo</th>
 +<th>bar
  </th></tr></table>
  
  !!end
  Empty table rows go away
  !! wikitext
  {|
 -| Hello
 -| there
 +|Hello
 +|there
  |- class="foo"
  |-
  |}
  !! html
  <table>
  <tr>
 -<td> Hello
 +<td>Hello
  </td>
 -<td> there
 +<td>there
  </td></tr>
  
  </table>
@@@ -28049,29 -26733,28 +28072,29 @@@ Indented table with an empty t
  
  !!end
  
 -## We have some newline diffs RT-ing this edge case
 -## and it is not important enough -- we seem to be emitting
 -## at most 2 newlines after a </tr> and this is unrelated to
 -## the issue from T85627 that this is testing.
 -!!test
 +!! test
  Indented table with blank lines in between (T85627)
 -!! options
 -parsoid=wt2html
  !! wikitext
   {|
   |foo
   
   
   |}
 -!! html
 +!! html/php
  <table>
 -
  <tr>
  <td>foo
 +<p><br /> 
 +</p>
  </td></tr></table>
  
 -!!end
 +!! html/parsoid
 + <table>
 + <tbody><tr><td>foo
 + <p>
 + <br /></p></td></tr>
 + </tbody></table>
 +!! end
  
  !!test
  Indented block & table
@@@ -28099,13 -26782,13 +28122,13 @@@ Indent and comment before table ro
  !! wikitext
  {|
   <!--hi-->|-
 - | there
 + |there
  |}
  !! html/php
  <table>
  
  <tr>
 -<td> there
 +<td>there
  </td></tr></table>
  
  !! html/parsoid
  </tbody></table>
  !! end
  
 -# Parsoid-specific since PHP parser doesn't handle this mixed tbl-wikitext
 +# PHP parser omits empty TR
  !!test
  Empty TR followed by a template-generated TR
 -!!options
 -parsoid
  !! wikitext
  {|
  |-
  {{echo|<tr><td>foo</td></tr>}}
  |}
 -!! html
 +!! html/php+tidy
 +<table>
 +
 +<tbody><tr><td>foo</td></tr>
 +</tbody></table>
 +!! html/parsoid
  <table>
  <tbody>
  <tr class='mw-empty-elt'></tr>
  </tbody></table>
  !!end
  
 -## PHP and parsoid output differ for this, and since this is primarily
 -## for testing Parsoid's serializer, marking this Parsoid only
 +## PHP and parsoid output differ for this; as usual PHP omits empty
 +## elements, and since it strips the comments the TR is empty.
  !!test
  Empty TR followed by mixed-ws-comment line should RT correctly
 -!!options
 -parsoid
  !! wikitext
  {|
  |-
  |-
  <!--c--> <!--d-->
  |}
 -!! html
 +!! html/php+tidy
 +<table>
 +
 +
 +</table>
 +!! html/parsoid
  <table>
  <tbody>
  <tr class='mw-empty-elt'></tr>
@@@ -28179,7 -26856,7 +28202,7 @@@ New element inserted (without interveni
  !! options
  parsoid=html2wt
  !! html/parsoid
 -<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>foo&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><p>new para</p>
 +<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>foo&lt;/includeonly>"}' data-mw='{"src":"&lt;includeonly>foo&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><p>new para</p>
  
  <link rel="mw:PageProp/Category" href="./Category:Foo" data-parsoid='{}'/><h1>new heading</h1>
  !! wikitext
@@@ -28210,91 -26887,87 +28233,91 @@@ Encapsulate protected attributes from w
  <div typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div>
  
  {| typeof="mw:placeholder stuff" data-mw="whoo" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true"
 -| ok
 +|ok
  |}
  !! html/parsoid
  <div data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div>
  
  <table data-x-typeof="mw:placeholder stuff" data-x-data-mw="whoo" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">
 -<tbody><tr><td data-parsoid='{"autoInsertedEnd":true}'> ok</td></tr>
 +<tbody><tr><td data-parsoid='{"autoInsertedEnd":true}'>ok</td></tr>
  </tbody></table>
  !!end
  
  ## Currently the p-wrapper is fragile in how it adds / removes transformations.
  ## Having nested or stray pre tags results in the attempt to add duplicates,
  ## causing an assertion fail. This test tries to prevent that situation.
 -!!test
 +!! test
  Ensure ParagraphWrapper can deal with stray closing pre tags
 -!!options
 +!! options
  parsoid=wt2html
  !! wikitext
  plain text</pre>
  !! html/parsoid
 -plain text
 -!!end
 +<p>plain text</p>
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  1. Ensure fostered text content is wrapped in element nodes
 -!!options
 +!! options
  parsoid=wt2html
  !! wikitext
  <table>hi</table><table>ho</table>
 +!! html/php+tidy
 +hi<table></table>ho<table></table>
  !! html/parsoid
 -<p>hi</p>
 -<table></table>
 -<p>ho</p>
 -<table></table>
 -!!end
 +<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>hi</p><table data-parsoid='{"stx":"html"}'></table><p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'>ho</p><table data-parsoid='{"stx":"html"}'></table>
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  2. Ensure fostered text content is wrapped in element nodes (traps regressions around fostered marker on the element getting lost)
 -!!options
 +!! options
  parsoid=wt2html,wt2wt
  !! wikitext
  <table>
  <tr> || ||
  <td> a
  </table>
 +!! html/php+tidy
 + || ||
 +<table>
 +<tbody><tr><td> a
 +</td></tr></tbody></table>
  !! html/parsoid
 -<p> || ||
 -</p><table>
 -<tbody><tr><td> a</td></tr>
 -</tbody></table>
 -!!end
 +<p data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true}'> || ||</p>
 +<table data-parsoid='{"stx":"html"}'>
 +<tbody><tr data-parsoid='{"stx":"html","autoInsertedEnd":true}'><td data-parsoid='{"stx":"html","autoInsertedEnd":true}'> a
 +</td></tr></tbody></table>
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  Encapsulation properly handles null DSR information from foster box
 -!!options
 +!! options
  parsoid=wt2html,wt2wt
  !! wikitext
  {{echo|<table>foo<tr><td>bar</td></tr></table>}}
  !! html/parsoid
 -<span typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;<table>foo<tr><td>bar</td></tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</span><table><tbody><tr><td>bar</td></tr></tbody></table>
 -!!end
 +<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;table>foo&lt;tr>&lt;td>bar&lt;/td>&lt;/tr>&lt;/table>"}},"i":0}}]}'>foo</p><table about="#mwt1" data-parsoid='{"stx":"html"}'><tbody><tr><td>bar</td></tr></tbody></table>
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  1. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table>{{echo|foo<tr><td>bar</td></tr>}}</table>
 +!! html/php+tidy
 +foo<table><tbody><tr><td>bar</td></tr></tbody></table>
  !! html/parsoid
 -<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo<tr><td>bar</td></tr>&quot;}},&quot;i&quot;:0}},&quot;</table>&quot;]}">foo</p><table>
 -<tbody>
 -<tr>
 -<td>bar</td>
 -</tr>
 -</tbody>
 -</table>
 -!!end
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;tr>&lt;td>bar&lt;/td>&lt;/tr>"}},"i":0}},"&lt;/table>"]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td>bar</td></tr></tbody></table>
 +!! end
  
 -!!test
 +!! test
  2. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table><div>{{echo|foo}}</div><tr><td>bar</td></tr></table>
  </tr>
  </tbody>
  </table>
 -!!end
 +!! end
  
 -!!test
 +!! test
  3. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
  </tr>
  </tbody>
  </table>
 -!!end
 +!! end
  
 -!!test
 +!! test
  4. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table>
  </tr>
  </tbody>
  </table>
 -!!end
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  5. Encapsulate foster-parented transclusion content
  !!options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table><tr><td><div><p>{{echo|foo</p></div></td>foo}}</tr></table>
 +!! html/php+tidy
 +foo<table><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table>
  !! html/parsoid
 -<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo&quot;}},&quot;i&quot;:0}},&quot;</tr></table>&quot;]}">foo</p>
 -<table>
 -<tbody>
 -<tr>
 -<td>
 -<div>
 -<p>foo</p>
 -</div>
 -</td>
 -</tr>
 -</tbody>
 -</table>
 -!!end
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>&lt;tr>&lt;td>&lt;div>&lt;p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;/p>&lt;/div>&lt;/td>foo"}},"i":0}},"&lt;/tr>&lt;/table>"]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table>
 +!! end
  
 -!!test
 +## Remex doesn't account for fostered content.
 +!! test
  6. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table><tr><td><div><p>{{echo|foo</p></div></td>foo</tr></table>}}<p>ok</p>
 +!! html/php+tidy
 +foo<table><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table><p>ok</p>
  !! html/parsoid
 -<p typeof="mw:Transclusion" data-mw="{&quot;parts&quot;:[&quot;<table><tr><td><div><p>&quot;,{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;foo</p></div></td>foo</tr></table>&quot;}},&quot;i&quot;:0}}]}">foo</p>
 -<table>
 -<tbody>
 -<tr>
 -<td>
 -<div>
 -<p>foo</p>
 -</div>
 -</td>
 -</tr>
 -</tbody>
 -</table>
 -<p>ok</p>
 -!!end
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>&lt;tr>&lt;td>&lt;div>&lt;p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo&lt;/p>&lt;/div>&lt;/td>foo&lt;/tr>&lt;/table>"}},"i":0}}]}'>foo</p><table about="#mwt2" data-parsoid='{"stx":"html"}'><tbody><tr><td><div><p>foo</p></div></td></tr></tbody></table><p data-parsoid='{"stx":"html"}'>ok</p>
 +!! end
  
 -!!test
 +!! test
  7. Encapsulate foster-parented transclusion content
  !!options
  parsoid=wt2wt,wt2html
  </tr>
  </tbody>
  </table>
 -!!end
 +!! end
  
 +## Remex doesn't account for fostered content.
  # Note that the wt is broken on purpose: the = should be {{=}} if you
  # don't want it to be a template parameter key.
 -!!test
 +!! test
  8. Encapsulate foster-parented transclusion content
 -!!options
 +!! options
  parsoid=wt2wt,wt2html
  !! wikitext
  {{echo|a
  |-
  |b
  |}
 -!! html/parsoid
 -<p typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}'>a</p>
 -<span> </span>
 -<p typeof="mw:Transclusion" data-mw='{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"&#39;color:red&#39;"}},"i":0}},"\n|-\n|b\n|}"]}'>{{{1}}}</p>
 +!! html/php+tidy
 +<p>a
 +</p>
  <table>
 -<tbody>
 -<tr>
 -<td>b</td>
 -</tr>
 -</tbody>
 -</table>
 -!!end
  
 -!!test
 +<tbody><tr>
 +<td>b
 +</td></tr></tbody></table>
 +!! html/parsoid
 +<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}'>a</p><span about="#mwt1">
 +</span><p about="#mwt3" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE","pi":[[{"k":"style","named":true}]]}' data-mw='{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"&apos;color:red&apos;"}},"i":0}},"\n|-\n|b\n|}"]}'>{{{1}}}</p><table about="#mwt3">
 +<tbody><tr>
 +<td>b
 +</td></tr></tbody></table>
 +!! end
 +
 +## Remex doesn't account for fostered content.
 +!! test
  9. Encapsulate foster-parented transclusion content
  !!options
  parsoid=wt2wt,wt2html
  !! wikitext
  <table>{{echo|hi</table>hello}}
 +!! html/php+tidy
 +hi<table></table><p>hello
 +</p>
  !! html/parsoid
 -<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;/table>hello"}},"i":0}}]}' data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"pi":[[{"k":"1"}]]}'>hi</p><table about="#mwt2" data-parsoid='{"stx":"html"}'></table><p about="#mwt2">hello</p>
 -!!end
 +<p about="#mwt2" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;/table>hello"}},"i":0}}]}'>hi</p><table about="#mwt2"></table><p about="#mwt2">hello</p>
 +!! end
  
 -!!test
 +!! test
  Table in fosterable position
  !!options
  parsoid=wt2html
  
  <table>
  </table>
 -!!end
 +!! end
  
  # Parsoid only for T66747
  !! test
@@@ -28468,11 -27150,9 +28491,11 @@@ Properly encapsulate empty-content tran
  </table>
  !! end
  
 +## No longer captures its original intention
  !! test
  Always encapsulate foster box when template range is expanded to table
  !! options
 +disabled
  parsoid=wt2wt
  !! wikitext
  {|
@@@ -28821,11 -27501,11 +28844,11 @@@ parsoid=
  
  !! test
  Image: empty alt attribute (T50924)
 -!! options
 -parsoid
  !! wikitext
  [[File:Foobar.jpg|thumb|alt=|bar]]
 -!! html
 +!! html/php+tidy
 +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>bar</div></div></div>
 +!! html/parsoid
  <figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"alt","ak":"alt="},{"ck":"caption","ak":"bar"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"}}'><img alt="" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"alt":"","resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"alt":"alt=","resource":"File:Foobar.jpg"}}'/></a><figcaption>bar</figcaption></figure>
  !! end
  
@@@ -29041,7 -27721,7 +29064,7 @@@ parsoid=html2w
  !! html/parsoid
  <ul><li>a<br>b</li><li>c</li></ul>
  !! wikitext
 -* a<br>b
 +* a<br />b
  * c
  !! end
  
@@@ -29098,7 -27778,7 +29121,7 @@@ parsoid=
  
  == hi pal ==
  
 -<!--foo-->  [[Category:A3]]
 +<!--foo-->[[Category:A3]]
  
  == how goes it ==
  
@@@ -29422,7 -28102,7 +29445,7 @@@ parsoid=
  !! html/parsoid
  <a rel="mw:WikiLink" href="./Football"><i>Foot</i></a><a rel="mw:WikiLink" href="./Football"><i>ball</i></a>
  !! wikitext
 -[[Football|''Football'']]
 +''[[Football]]''
  !! end
  
  !! test
@@@ -29438,115 -28118,6 +29461,115 @@@ parsoid=
  [[Football|Foot]][[Football|ball]]
  !! end
  
 +!! test
 +1. Move format tags outside of WikiLink
 +!! options
 +parsoid={
 +  "modes": ["html2wt"],
 +  "scrubWikitext": true
 +}
 +!! html/parsoid
 +<a rel="mw:WikiLink" href="./Football"><i>Football</i></a>
 +<a rel="mw:WikiLink" href="./Football"><i><b>Football</b></i></a>
 +<a rel="mw:WikiLink" href="./Football"><u><i><b>Football</b></i></u></a>
 +!! wikitext
 +''[[Football]]''
 +'''''[[Football]]'''''
 +<u>'''''[[Football]]'''''</u>
 +!! end
 +
 +!! test
 +2. Move format tags outside of WikiLink with mergable A tags
 +!! options
 +parsoid={
 +  "modes": ["html2wt"],
 +  "scrubWikitext": true
 +}
 +!! html/parsoid
 +<a rel="mw:WikiLink" href="./Football"><i><b>Foot</b></i></a><a rel="mw:WikiLink" href="./Football"><i><b>ball</b></i></a>
 +!! wikitext
 +'''''[[Football]]'''''
 +!! end
 +
 +!! test
 +3. Move format tags outside of WikiLink while preserving formats already outside WikiLink
 +!! options
 +parsoid={
 +  "modes": ["html2wt"],
 +  "scrubWikitext": true
 +}
 +!! html/parsoid
 +<font color="red"><a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><u><b>Foo</b></u></a></font>
 +!! wikitext
 +<font color="red"><u>'''[[Foo]]'''</u></font>
 +!! end
 +
 +!! test
 +4. Do not move format tags outside of WikiLink which includes attributes color, style and class
 +!! options
 +parsoid={
 +  "modes": ["html2wt"],
 +  "scrubWikitext": true
 +}
 +!! html/parsoid
 +<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><font color="red">Foo</font></a>
 +<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><span style="color: blue; font-size: 46px;">Foo></span></a>
 +<a rel="mw:WikiLink" href="./Foo" title="Foo" class="mw-redirect"><span class="Bar">Foo</span></a>
 +!! wikitext
 +[[Foo|<font color="red">Foo</font>]]
 +[[Foo|<span style="color: blue; font-size: 46px;">Foo></span>]]
 +[[Foo|<span class="Bar">Foo</span>]]
 +!! end
 +
 +!! test
 +5. T194083 Regression test: Manual edit test that also enables scrubWikitext to move format tags outside wikilinks
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "scrubWikitext": true,
 +  "changes": [
 +    ["a", "html", "<i>Foo</i>"]
 +  ]
 +}
 +!! wikitext
 +[[Foo]]
 +!! wikitext/edited
 +''[[Foo]]''
 +!! end
 +
 +!! test
 +6. Regression test: Manual edit test to ensure diff markers are not lost
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "scrubWikitext": true,
 +  "changes": [
 +    ["i", "wrap", "<a href='./Foo' rel='mw:WikiLink'></a>"]
 +  ]
 +}
 +!! wikitext
 +''Foo''
 +!! wikitext/edited
 +''[[Foo]]''
 +!! end
 +
 +!! test
 +7. T194083 Regression test: Manual edit test to ensure nested diff markers aren't inserted
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "scrubWikitext": true,
 +  "changes": [
 +    ["div", "after", "\n<p><a href='./Foo' rel='mw:WikiLink'>Foo </a>, placeholder</p>"]
 +  ]
 +}
 +!! wikitext
 +<div>placeholder</div>
 +!! wikitext/edited
 +<div>placeholder</div>
 +[[Foo]] , placeholder
 +!! end
 +
  #------------------------------
  # End of tag minimization tests
  #------------------------------
@@@ -29786,8 -28357,8 +29809,8 @@@ Magic links inside image captions (auto
  <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div><a href="/wiki/Special:BookSources/123456789X" class="internal mw-magiclink-isbn">ISBN 123456789x</a></div></div></div>
  !! html/parsoid
  <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a rel="mw:ExtLink" class="external free" href="http://example.com">http://example.com</a></figcaption></figure>
 -<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external text">RFC 1234</a></figcaption></figure>
 -<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external text">PMID 1234</a></figcaption></figure>
 +<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="https://tools.ietf.org/html/rfc1234" rel="mw:ExtLink" class="external mw-magiclink">RFC 1234</a></figcaption></figure>
 +<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" rel="mw:ExtLink" class="external mw-magiclink">PMID 1234</a></figcaption></figure>
  <figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption><a href="./Special:BookSources/123456789X" rel="mw:WikiLink">ISBN 123456789x</a></figcaption></figure>
  !! end
  
@@@ -29850,9 -28421,10 +29873,9 @@@ parsoid=html2wt,wt2w
  |<nowiki>- </nowiki>
  |-
  |<small>-</small>
 -|<br>
 --
 -|<br>
 +|<br />
  -
 +|<br />-
  |}
  !! html/php+tidy
  <table>
  <p>-
  </p>
  </td>
 -<td><br />
 -<p>-
 -</p>
 +<td><br />-
  </td></tr></tbody></table>
  !! end
  
@@@ -29998,222 -28572,65 +30021,222 @@@ parsoid=html2w
  !! end
  
  !! test
 -WTS change modes
 +Testing serialization after deletion in references
  !! options
  parsoid={
    "modes": ["wt2wt"],
    "changes": [
 -    [ "#xyz", "before", "<b>before</b> stuff " ],
 -    [ "#xyz", "after", " stuff <i>after</i>" ],
 -    [ "#xyz", "html", "x <b>y</b> z" ]
 +    ["#x", "remove"]
    ]
  }
  !! wikitext
 -<span id="xyz">hello</span>
 +hi <ref><div id="x">ho</div></ref>
 +
 +<references />
  !! wikitext/edited
 -'''before''' stuff <span id="xyz">x '''y''' z</span> stuff ''after''
 -!! end
 +hi <ref></ref>
  
 -!! test
 -Never serialize a-tag as html, regardless of what data-parsoid has to say
 -!! options
 -parsoid={ "modes": ["html2wt"], "suppressErrors": true }
 -!! html/parsoid
 -<a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{"stx":"html"}'>Foo</a>
 -!! wikitext
 -[[Foo]]
 +<references />
  !! end
  
 -## SSS FIXME: This is broken output nevertheless.
 -## What might be a reasonable non-broken output for this?
 -## This is an edge case unlikely to be seen in production
 -## that I am not wasting more time on this right now.
 +!!test
 +Testing serialization after deletion of table cells
 +!!options
 +parsoid={
 +  "modes": ["wt2wt", "selser"],
 +  "changes": [
 +    ["#x", "remove"]
 +  ]
 +}
 +!!wikitext
 +{|
 +!h1 !!h2 !!h3
 +| id="x" |c1 {{!}}{{!}}{{!}}c2 |||c3
 +|}
 +!! wikitext/edited
 +{|
 +!h1!!h2!!h3
 +|c2|||c3
 +|}
 +!!end
 +
  !! test
 -Never serialize a-tag as html, no matter what attributes it has
 +Testing selser after addition of new row before first row (T125419)
  !! options
 -parsoid={ "modes": ["html2wt"], "suppressErrors": true }
 -!! html/parsoid
 -<a bad='true' href='http://boo.org'><img src='http://boohoo.org' /></a>
 +parsoid={
 +  "modes": ["wt2wt", "selser"],
 +  "changes": [
 +    [ "tr", "before", "<tr><td>X</td></tr>" ]
 +  ]
 +}
  !! wikitext
 -[http://boo.org http://boohoo.org]
 +{|
 +|a
 +|}
 +!! wikitext/edited
 +{|
 +|X
 +|-
 +|a
 +|}
  !! end
  
 -# Misnested is an indication that selser can reuse the source but these have
 -# shown to sneak through on occasion. See T101768.
 -# The original wikitext here is: [http://test.com [[one]] two three]
  !! test
 -Strip span tags added to mark misnested links
 +Serialize new table rows in a HTML table using HTML tags
  !! options
 -parsoid=html2wt
 -!! html/parsoid
 -<p data-parsoid='{}'><a rel="mw:ExtLink" href="http://test.com" data-parsoid='{"targetOff":17,"contentOffsets":[17,34]}'></a><a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"simple","a":{"href":"./One"},"sa":{"href":"one"},"misnested":true}'>one</a><span data-parsoid='{"misnested":true}'> two three</span></p>
 +parsoid={
 +  "modes": ["wt2wt", "selser"],
 +  "changes": [
 +    [ "tr", "before", "<tr><td>X</td></tr>" ]
 +  ]
 +}
  !! wikitext
 -[http://test.com][[one]] two three
 +<table><tr><td>a</td></tr></table>
 +!! wikitext/edited
 +<table><tr><td>X</td></tr><tr><td>a</td></tr></table>
  !! end
  
  !! test
 -Catch regression when unpacking misnested links
 +Serialize new table cells in a HTML row using HTML tags
  !! options
 -parsoid=wt2html
 -!! wikitext
 -{{echo|hi}}[http://example.com [[ho]]]
 +parsoid={
 +  "modes": ["wt2wt", "selser"],
 +  "changes": [
 +    [ "td", "before", "<td>X</td>" ]
 +  ]
 +}
 +!! wikitext
 +<table><tr><td>a</td></tr></table>
 +!! wikitext/edited
 +<table><tr><td>X</td><td>a</td></tr></table>
 +!! end
 +
 +!! test
 +Serialize wikitext list items as HTML list items when embedded in a HTML list
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<ul data-parsoid='{"stx": "html"}'>
 +<li data-parsoid='{}'>a</li>
 +<li>b</li>
 +</ul>
 +!! wikitext
 +<ul>
 +<li>a</li>
 +<li>b</li>
 +</ul>
 +!! html/php+tidy
 +<ul>
 +<li>a</li>
 +<li>b</li>
 +</ul>
 +!! end
 +
 +# Nested list should be inside <li>, that is
 +# <ul><li>foo<ul>..</ul></li></ul> instead of
 +# <ul><li>foo</li><ul>..</ul></ul>
 +# See https://stackoverflow.com/questions/5899337/proper-way-to-make-html-nested-list
 +!! test
 +Wikitext lists can be nested inside HTML lists
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<ul data-parsoid='{"stx": "html"}'>
 +<li data-parsoid='{"stx": "html"}'>a
 +<ul><li>b</li></ul>
 +</li>
 +</ul>
 +
 +<ul data-parsoid='{"stx": "html"}'>
 +<li>x
 +<ul><li>y</li></ul>
 +</li>
 +</ul>
 +!! wikitext
 +<ul>
 +<li>a
 +* b
 +</li>
 +</ul>
 +
 +<ul>
 +<li>x
 +* y
 +</li>
 +</ul>
 +!! html/php+tidy
 +<ul>
 +<li>a
 +<ul><li>b</li></ul>
 +</li>
 +</ul>
 +<ul>
 +<li>x
 +<ul><li>y</li></ul>
 +</li>
 +</ul>
 +!! end
 +
 +!! test
 +WTS change modes
 +!! options
 +parsoid={
 +  "modes": ["wt2wt"],
 +  "changes": [
 +    [ "#xyz", "before", "<b>before</b> stuff " ],
 +    [ "#xyz", "after", " stuff <i>after</i>" ],
 +    [ "#xyz", "html", "x <b>y</b> z" ]
 +  ]
 +}
 +!! wikitext
 +<span id="xyz">hello</span>
 +!! wikitext/edited
 +'''before''' stuff <span id="xyz">x '''y''' z</span> stuff ''after''
 +!! end
 +
 +!! test
 +Never serialize a-tag as html, regardless of what data-parsoid has to say
 +!! options
 +parsoid={ "modes": ["html2wt"], "suppressErrors": true }
 +!! html/parsoid
 +<a rel="mw:WikiLink" href="./Foo" title="Foo" data-parsoid='{"stx":"html"}'>Foo</a>
 +!! wikitext
 +[[Foo]]
 +!! end
 +
 +## SSS FIXME: This is broken output nevertheless.
 +## What might be a reasonable non-broken output for this?
 +## This is an edge case unlikely to be seen in production
 +## that I am not wasting more time on this right now.
 +!! test
 +Never serialize a-tag as html, no matter what attributes it has
 +!! options
 +parsoid={ "modes": ["html2wt"], "suppressErrors": true }
 +!! html/parsoid
 +<a bad='true' href='http://boo.org'><img src='http://boohoo.org' /></a>
 +!! wikitext
 +[http://boo.org http://boohoo.org]
 +!! end
 +
 +# Misnested is an indication that selser can reuse the source but these have
 +# shown to sneak through on occasion. See T101768.
 +# The original wikitext here is: [http://test.com [[one]] two three]
 +!! test
 +Strip span tags added to mark misnested links
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<p data-parsoid='{}'><a rel="mw:ExtLink" href="http://test.com" data-parsoid='{"targetOff":17,"contentOffsets":[17,34]}'></a><a rel="mw:WikiLink" href="./One" title="One" data-parsoid='{"stx":"simple","a":{"href":"./One"},"sa":{"href":"one"},"misnested":true}'>one</a><span data-parsoid='{"misnested":true}'> two three</span></p>
 +!! wikitext
 +[http://test.com][[one]] two three
 +!! end
 +
 +!! test
 +Catch regression when unpacking misnested links
 +!! options
 +parsoid=wt2html
 +!! wikitext
 +{{echo|hi}}[http://example.com [[ho]]]
  !! html/parsoid
  <p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi"}},"i":0}}]}'>hi</span><a rel="mw:ExtLink" class="external autonumber" href="http://example.com"></a><a rel="mw:WikiLink" href="./Ho" title="Ho" data-parsoid='{"misnested":true}'>ho</a></p>
  !! end
@@@ -30391,7 -28808,7 +30414,7 @@@ parsoid=
  !! html/parsoid
  <h2> <link href="./Category:A2" rel="mw:PageProp/Category" />ok</h2>
  !! wikitext
 - [[Category:A2]]
 +[[Category:A2]]
  
  == ok ==
  !! end
@@@ -30459,7 -28876,7 +30482,7 @@@ parsoid=
  !! html/parsoid
  <h2>foo<br/>bar</h2>
  !! wikitext
 -== foo<brbar ==
 +== foo<br />bar ==
  !! end
  
  !! test
@@@ -30595,7 -29012,7 +30618,7 @@@ parsoid=
    "modes": ["html2wt"],
    "scrubWikitext": true
  }
 -!! html
 +!! html/parsoid
  <h2><i></i></h2>
  <p><a href='Foo' rel='mw:WikiLink'>foo<i></i>
   </a><b><i></i></b>x</p>
@@@ -30613,14 -29030,15 +30636,14 @@@ parsoid=
    "modes": ["selser"],
    "scrubWikitext": true,
    "changes": [
 -    [ "#x", "after", "<h1><i></i></h1>\n<p> x<b></b></p>"]
 +    [ "#x", "after", "<h1><i></i></h1>\n<p> bar<b></b></p>"]
    ]
  }
  !! wikitext
 -<span id="x">foo</span>
 +<div id="x">foo</div>
  !! wikitext/edited
 -<span id="x">foo</span>
 -
 -x
 +<div id="x">foo</div>
 +bar
  !! end
  
  !! test
@@@ -30753,12 -29171,11 +30776,12 @@@ parsoid=
    "modes": ["html2wt"],
    "scrubWikitext": false
  }
 -!! html
 +!! html/parsoid
  <table>
  <tr><td>a</td></tr>
  <tr><td>-</td></tr>
  <tr><td>+</td></tr>
 +<tr><td>}</td></tr>
  </table>
  !! wikitext
  {|
  |<nowiki>-</nowiki>
  |-
  |<nowiki>+</nowiki>
 +|-
 +|<nowiki>}</nowiki>
  |}
  !! end
  
@@@ -30779,12 -29194,11 +30802,12 @@@ parsoid=
    "modes": ["html2wt"],
    "scrubWikitext": true
  }
 -!! html
 +!! html/parsoid
  <table>
  <tr><td>a</td></tr>
  <tr><td>-</td></tr>
  <tr><td>+</td></tr>
 +<tr><td>}</td></tr>
  </table>
  !! wikitext
  {|
  | -
  |-
  | +
 +|-
 +| }
  |}
  !! end
  
@@@ -30939,7 -29351,7 +30962,7 @@@ parsoid=
    "modes": ["html2wt"],
    "scrubWikitext": true
  }
 -!! html
 +!! html/parsoid
  <font>foo</font>
  <font><font>bar</font></font>
  <font class="x">boo</font>
@@@ -30956,7 -29368,7 +30979,7 @@@ parsoid=
    "modes": ["html2wt"],
    "scrubWikitext": false
  }
 -!! html
 +!! html/parsoid
  <font>foo</font>
  !! wikitext
  <font>foo</font>
  }}
  !! end
  
 +!! test
 +New list is serialized on newlines
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<p>The quick brown fox jumps over the lazy dog.</p><ul>
 +<li>Yesterday</li>
 +<li>Today</li>
 +<li>Tomorrow</li>
 +</ul><p>The quick onyx goblin jumps over the lazy dwarf.</p>
 +!! wikitext
 +The quick brown fox jumps over the lazy dog.
 +
 +* Yesterday
 +* Today
 +* Tomorrow
 +
 +The quick onyx goblin jumps over the lazy dwarf.
 +!! end
 +
 +!! test
 +New lists in formatting elements serialized w/o newlines
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<small>
 +
 +<ul>
 +<li>123</li>
 +</ul>
 +
 +</small>
 +
 +<small><ul><li>hi</li></ul></small>
 +!! wikitext
 +<small>
 +* 123
 +</small>
 +
 +<small>
 +* hi
 +</small>
 +!! end
 +
 +!! test
 +New list in table doesn't need newlines
 +!! options
 +parsoid=html2wt
 +!! html/parsoid
 +<table><tr><td><ul><li>test</li><li>123</li></td></tr></table>
 +!! wikitext
 +{|
 +|
 +* test
 +* 123
 +|}
 +!! end
 +
  # ---------------------------------------------------
  # End of tests spec'ing wikitext serialization norms |
  # ---------------------------------------------------
@@@ -31232,15 -29586,15 +31255,15 @@@ parsoid=
  !! test
  Empty LI (T49673)
  !! wikitext
 -* a
 +*a
  * 
  *
 -* b
 +*b
  !! html+tidy
 -<ul><li> a</li>
 -<li class="mw-empty-elt"> </li>
 +<ul><li>a</li>
  <li class="mw-empty-elt"></li>
 -<li> b</li></ul>
 +<li class="mw-empty-elt"></li>
 +<li>b</li></ul>
  !! end
  
  !! test
@@@ -31278,18 -29632,8 +31301,18 @@@ styletag=
  <style>.foo::before { content: "<foo>"; }</style>
  <style data-mw-foobar="baz">.foo::after { content: "<bar>"; }</style>
  </div>
 +!! html/parsoid
 +<div class="foo">
 +<style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style>
 +<style data-x-data-mw-foobar="baz" typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{"data-x-data-mw-foobar":"baz"},"body":{"extsrc":".foo::after { content: \"&lt;bar>\"; }"}}'>.foo::after { content: "<bar>"; }</style>
 +</div>
  !! end
  
 +## Right now, Parsoid doesn't de-duplicate style tags.
 +## So, we shouldn't see link tags that need to bypass the sanitizer.
 +## In a followup patch, when we de-duplicate style tags and
 +## introduce link tags, we'll add a hook for link tags in
 +## the parser test runner script.
  !! test
  Validating that <style> isn't wrapped in a paragraph (T186965)
  !! options
  <style>.foo::before { content: "<foo>"; }</style>
  bar
  </p>
 +!! html/parsoid
 +<p>A style tag, by itself or with other style/link tags, shouldn't be wrapped in a paragraph</p>
 +
 +<style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style>
 +
 +<p><style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style> &lt;link rel="foo" href="bar"/><style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style></p>
 +
 +<p>But if it's on a line with other content, let it be wrapped.</p>
 +
 +<p><style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style> bar</p>
 +
 +<p>foo <style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style></p>
 +
 +<p>foo <style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style> bar</p>
 +
 +<p>And the same if we have non-paragraph-breaking whitespace</p>
 +
 +<p>foo
 +<style typeof="mw:Extension/style" data-mw='{"name":"style","attrs":{},"body":{"extsrc":".foo::before { content: \"&lt;foo>\"; }"}}'>.foo::before { content: "<foo>"; }</style>
 +bar</p>
  !! end
  
  !! test
  </p>
  !! end
  
 +!! test
 +Extension returning multiple nodes starting with a style tag roundtrips
 +!! options
 +wgRawHtml=1
 +!! wikitext
 +<table>
 +{{echo|<html><style>.hi { color: red; }</style>
 +</html>}}
 +<tr><td class="hi">ho</td></tr>
 +</table>
 +!! html/parsoid
 +<p about="#mwt5" typeof="mw:Transclusion" data-parsoid='{"fostered":true,"autoInsertedEnd":true,"autoInsertedStart":true,"firstWikitextNode":"TABLE_html","pi":[[{"k":"1"}]]}' data-mw='{"parts":["&lt;table>\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;html>&lt;style>.hi { color: red; }&lt;/style>\n&lt;/html>"}},"i":0}},"\n&lt;tr>&lt;td class=\"hi\">ho&lt;/td>&lt;/tr>\n&lt;/table>"]}'><style typeof="mw:Extension/html" about="#mwt4" data-mw='{"name":"html","attrs":{},"body":{"extsrc":"&lt;style>.hi { color: red; }&lt;/style>\n"}}'>.hi { color: red; }</style><span about="#mwt4">
 +</span></p><table about="#mwt5" data-parsoid='{"stx":"html"}'>
 +
 +<tbody><tr><td class="hi">ho</td></tr>
 +</tbody></table>
 +!! end
 +
  !! test
  Decoding of HTML entities in headings and links for IDs and link fragments (T103714)
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
 -== A&B&amp;C&amp;amp;D&amp;amp;amp;E ==
 +==A&B&amp;C&amp;amp;D&amp;amp;amp;E==
  [[#A&B&amp;C&amp;amp;D&amp;amp;amp;E]]
  !! html/php
  <h2><span id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE"></span><span class="mw-headline" id="A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E">A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  <p><a href="#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E">#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a>
  </p>
  !! html/parsoid
 -<h2 id="A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"><span id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE" typeof="mw:FallbackId" data-parsoid="{}"></span> A&amp;B<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>C<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;D<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;amp;E </h2>
 -<p><a rel="mw:WikiLink" href="./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
 +<h2 id="A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"><span id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE" typeof="mw:FallbackId" data-parsoid="{}"></span>A&amp;B<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>C<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;D<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;amp;E</h2>
 +<p><a rel="mw:WikiLink" href="./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
  !! end
  
  !! test
@@@ -31429,7 -29735,7 +31452,7 @@@ Decoding of HTML entities in headings a
  !! config
  wgFragmentMode=[ 'legacy' ]
  !! wikitext
 -== A&B&amp;C&amp;amp;D&amp;amp;amp;E ==
 +==A&B&amp;C&amp;amp;D&amp;amp;amp;E==
  [[#A&B&amp;C&amp;amp;D&amp;amp;amp;E]]
  !! html/php
  <h2><span class="mw-headline" id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE">A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
@@@ -31482,17 -29788,17 +31505,17 @@@ HTML5 ids: fallback to legac
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
 -== Foo bar ==
 +==Foo bar==
  
 -== foo Bar ==
 +==foo Bar==
  
 -== Тест ==
 +==Тест==
  
 -== Тест ==
 +==Тест==
  
 -== тест ==
 +==тест==
  
 -== Hey < # " > % : ' ==
 +==Hey < # " > % : '==
  [[#Foo bar]] [[#foo Bar]] [[#Тест]] [[#тест]] [[#Hey < # " > % : ']]
  
  {{anchorencode:💩}} <span id="{{anchorencode:💩}}"></span>
  [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
  
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
  </p><p><a href="#啤酒">#啤酒</a> <a href="#啤酒">#啤酒</a>
  </p>
  !! html/parsoid
 -<h2 id="Foo_bar"> Foo bar </h2>
 +<h2 id="Foo_bar">Foo bar</h2>
  
 -<h2 id="foo_Bar_2"> foo Bar </h2>
 +<h2 id="foo_Bar_2">foo Bar</h2>
  
 -<h2 id="Тест"><span id=".D0.A2.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span> Тест </h2>
 +<h2 id="Тест"><span id=".D0.A2.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span>Тест</h2>
  
 -<h2 id="Тест_2"><span id=".D0.A2.D0.B5.D1.81.D1.82_2" typeof="mw:FallbackId"></span> Тест </h2>
 +<h2 id="Тест_2"><span id=".D0.A2.D0.B5.D1.81.D1.82_2" typeof="mw:FallbackId"></span>Тест</h2>
  
 -<h2 id="тест"><span id=".D1.82.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span> тест </h2>
 +<h2 id="тест"><span id=".D1.82.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span>тест</h2>
  
 -<h2 id="Hey_&lt;_#_&quot;_>_%_:_'"><span id="Hey_.3C_.23_.22_.3E_.25_:_.27" typeof="mw:FallbackId"></span> Hey &lt; # " > %<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span>: ' </h2>
 -<p><a rel="mw:WikiLink" href="./Main_Page#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Main_Page#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Main_Page#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Main_Page#тест">#тест</a> <a rel="mw:WikiLink" href="./Main_Page#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
 +<h2 id="Hey_&lt;_#_&quot;_>_%_:_'"><span id="Hey_.3C_.23_.22_.3E_.25_:_.27" typeof="mw:FallbackId"></span>Hey &lt; # " > %<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span>: '</h2>
 +<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Parser_test#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Parser_test#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Parser_test#тест">#тест</a> <a rel="mw:WikiLink" href="./Parser_test#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
  
 -<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"anchorencode:💩","function":"anchorencode"},"params":{},"i":0}}]}'>💩</span> <span id="💩" about="#mwt3" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[190,209,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:💩\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&#39;>💩&lt;/span>"}]]}'></span></p>
 +<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"anchorencode:💩","function":"anchorencode"},"params":{},"i":0}}]}'>💩</span> <span id="💩" about="#mwt3" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[178,197,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:💩\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&#39;>💩&lt;/span>"}]]}'></span></p>
  
  <!-- These two links should produce identical HTML -->
 -<p><a rel="mw:WikiLink" href="./Main_Page#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Main_Page#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
 +<p><a rel="mw:WikiLink" href="./Parser_test#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Parser_test#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
  !! end
  
  # Parsoid doesn't support this mode
@@@ -31548,17 -29854,17 +31571,17 @@@ HTML5 ids: legacy with a fallback to mo
  !! config
  wgFragmentMode=[ 'legacy', 'html5' ]
  !! wikitext
 -== Foo bar ==
 +==Foo bar==
  
 -== foo Bar ==
 +==foo Bar==
  
 -== Тест ==
 +==Тест==
  
 -== Тест ==
 +==Тест==
  
 -== тест ==
 +==тест==
  
 -== Hey < # " > % : ' ==
 +==Hey < # " > % : '==
  [[#Foo bar]] [[#foo Bar]] [[#Тест]] [[#тест]] [[#Hey < # " > % : ']]
  
  {{anchorencode:💩}} <span id="{{anchorencode:💩}}"></span>
  [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
  
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
@@@ -31596,17 -29902,17 +31619,17 @@@ HTML5 ids: no legac
  !! config
  wgFragmentMode=[ 'html5' ]
  !! wikitext
 -== Foo bar ==
 +==Foo bar==
  
 -== foo Bar ==
 +==foo Bar==
  
 -== Тест ==
 +==Тест==
  
 -== Тест ==
 +==Тест==
  
 -== тест ==
 +==тест==
  
 -== Hey < # " > % : ' ==
 +==Hey < # " > % : '==
  [[#Foo bar]] [[#foo Bar]] [[#Тест]] [[#тест]] [[#Hey < # " > % : ']]
  
  {{anchorencode:💩}} <span id="{{anchorencode:💩}}"></span>
  [[#啤酒]] [[#%E5%95%A4%E9%85%92]]
  
  !! html/php
 -<div id="toc" class="toc"><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2></div>
 +<div id="toc" class="toc"><input type="checkbox" role="button" id="toctogglecheckbox" class="toctogglecheckbox" style="display:none"/><div class="toctitle" lang="en" dir="ltr"><h2>Contents</h2><span class="toctogglespan"><label class="toctogglelabel" for="toctogglecheckbox"></label></span></div>
  <ul>
  <li class="toclevel-1 tocsection-1"><a href="#Foo_bar"><span class="tocnumber">1</span> <span class="toctext">Foo bar</span></a></li>
  <li class="toclevel-1 tocsection-2"><a href="#foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext">foo Bar</span></a></li>
@@@ -31643,16 -29949,13 +31666,16 @@@ T90902: Normalize weird characters in s
  !! config
  wgFragmentMode=[ 'html5', 'legacy' ]
  !! wikitext
 -== Foo&nbsp;bar ==
 +==Foo&nbsp;bar==
  [[#Foo&nbsp;bar]]
  
  !! html/php
  <h2><span class="mw-headline" id="Foo_bar">Foo&#160;bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
  <p><a href="#Foo_bar">#Foo&#160;bar</a>
  </p>
 +!! html/parsoid
 +<h2 id="Foo_bar"> Foo<span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span>bar </h2>
 +<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Foo_bar"},"sa":{"href":"#Foo&amp;nbsp;bar"}}'>#Foo bar</a></p>
  !! end
  
  !! test
@@@ -31685,20 -29988,6 +31708,20 @@@ T72875: Test for brackets in attribute
  <a rel="mw:WikiLink" href="./Foo" title="Foo">link <span title="title with [[double brackets]]" data-parsoid='{"stx":"html","a":{"title":"title with [[double brackets]]"},"sa":{"title":"title with &amp;#91;&amp;#91;double brackets&amp;#93;&amp;#93;"}}'>span</span></a></p>
  !! end
  
 +!! test
 +T199926: html arrow wt: Parsoid sometimes trips up on verticalbar chars in hrefs
 +!! options
 +parsoid={
 +  "modes": ["html2wt"]
 +}
 +!! html/parsoid
 +<a href="https://stats.wikimedia.org/v2/#/fr.wikipedia.org/reading/page-views-by-country/normal|map|2-Year~2016060100~2018071100|~total">9</a>
 +<a href="https://stats.wikimedia.org/v2/#/fr.wikipedia.org/reading/page-views-by-country/normal%7Cmap%7C2-Year~2016060100~2018071100%7C~total">10</a>
 +!! wikitext
 +[https://stats.wikimedia.org/v2/#/fr.wikipedia.org/reading/page-views-by-country/normal|map|2-Year~2016060100~2018071100|~total 9]
 +[[stats:v2/#/fr.wikipedia.org/reading/page-views-by-country/normal%7Cmap%7C2-Year~2016060100~2018071100%7C~total|10]]
 +!! end
 +
  !! test
  T179544: {{anchorencode:}} output should be always usable in links
  !! config
@@@ -31709,7 -29998,7 +31732,7 @@@ wgFragmentMode=[ 'html5' 
  <p><span id="&#91;foo&#93;"></span><a href="#[foo]">#&#91;foo&#93;</a>
  </p>
  !! html/parsoid
 -<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Main_Page#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
 +<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Parser_test#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
  !! end
  
  ## ------------------------------
@@@ -31722,40 -30011,40 +31745,40 @@@ parsoid=
    "wrapSections": true
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
 -= 2 =
 +=2=
  b
  
 -== 2.1 ==
 +==2.1==
  c
  
 -== 2.2 ==
 +==2.2==
  d
  
 -=== 2.2.1 ===
 +===2.2.1===
  e
  
 -= 3 =
 +=3=
  f
  !! html/parsoid
 -<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -</section><section data-mw-section-id="2"><h1 id="2"> 2 </h1>
 +</section><section data-mw-section-id="2"><h1 id="2">2</h1>
  <p>b</p>
  
 -<section data-mw-section-id="3"><h2 id="2.1"> 2.1 </h2>
 +<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
  <p>c</p>
  
 -</section><section data-mw-section-id="4"><h2 id="2.2"> 2.2 </h2>
 +</section><section data-mw-section-id="4"><h2 id="2.2">2.2</h2>
  <p>d</p>
  
 -<section data-mw-section-id="5"><h3 id="2.2.1"> 2.2.1 </h3>
 +<section data-mw-section-id="5"><h3 id="2.2.1">2.2.1</h3>
  <p>e</p>
  
 -</section></section></section><section data-mw-section-id="6"><h1 id="3"> 3 </h1>
 +</section></section></section><section data-mw-section-id="6"><h1 id="3">3</h1>
  <p>f</p>
  
  </section>
@@@ -31774,13 -30063,13 +31797,13 @@@ Para 2 with a <div>nested in it</div
  
  Para 3.
  
 -= 1 =
 +=1=
  a
  
 -= 2 =
 +=2=
  b
  
 -== 2.1 ==
 +==2.1==
  c
  !! html/parsoid
  <section data-mw-section-id="0"><p>Para 1.</p>
  
  <p>Para 3.</p>
  
 -</section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +</section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -</section><section data-mw-section-id="2"><h1 id="2"> 2 </h1>
 +</section><section data-mw-section-id="2"><h1 id="2">2</h1>
  <p>b</p>
  
 -<section data-mw-section-id="3"><h2 id="2.1"> 2.1 </h2>
 +<section data-mw-section-id="3"><h2 id="2.1">2.1</h2>
  <p>c</p>
  
  </section></section>
@@@ -31808,29 -30097,29 +31831,29 @@@ parsoid=
    "wrapSections": true
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
  {{echo|1=
 -== 1.1 ==
 +==1.1==
  b
  }}
  
 -== 1.2 ==
 +==1.2==
  c
  
 -= 2 =
 +=2=
  d
  !! html/parsoid
 -<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,33,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.1 ==\nb"}},"i":0}}]}'> 1.1 </h2><span about="#mwt1">
 +<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,33,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.1==\nb"}},"i":0}}]}'>1.1</h2><span about="#mwt1">
  </span><p about="#mwt1">b</p>
 -</section><section data-mw-section-id="3"><h2 id="1.2"> 1.2 </h2>
 +</section><section data-mw-section-id="3"><h2 id="1.2">1.2</h2>
  <p>c</p>
  
 -</section></section><section data-mw-section-id="4"><h1 id="2"> 2 </h1>
 +</section></section><section data-mw-section-id="4"><h1 id="2">2</h1>
  <p>d</p></section>
  !! end
  
@@@ -31844,26 -30133,26 +31867,26 @@@ parsoid=
    "modes": ["wt2html", "wt2wt"]
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
  {{echo|1=
 -== 1.1 ==
 +==1.1==
  b
 -=== 1.1.1 ===
 +===1.1.1===
  d
  }}
 -= 2 =
 +=2=
  e
  !! html/parsoid
 -<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,50,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.1 ==\nb\n=== 1.1.1 ===\nd"}},"i":0}},"\n"]}'> 1.1 </h2><span about="#mwt1">
 +<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.1" data-parsoid='{"dsr":[9,50,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.1==\nb\n===1.1.1===\nd"}},"i":0}},"\n"]}'>1.1</h2><span about="#mwt1">
  </span><p about="#mwt1">b</p><span about="#mwt1">
 -</span><section data-mw-section-id="-1" about="#mwt1"><h3 about="#mwt1" id="1.1.1"> 1.1.1 </h3><span about="#mwt1">
 +</span><section data-mw-section-id="-1" about="#mwt1"><h3 about="#mwt1" id="1.1.1">1.1.1</h3><span about="#mwt1">
  </span><p about="#mwt1">d</p><span about="#mwt1">
 -</span></section></section></section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="2"> 2 </h1>
 +</span></section></section></section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="2">2</h1>
  <p>e</p></section>
  !! end
  
@@@ -31877,32 -30166,32 +31900,32 @@@ parsoid=
    "modes": ["wt2html", "wt2wt"]
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
  {{echo|1=
  x
 -== 1.1 ==
 +==1.1==
  b
  ==1.2==
  c
  ===1.2.1===
  d
  }}
 -= 2 =
 +=2=
  e
  !! html/parsoid
  <section data-mw-section-id="0"></section><section data-mw-section-id="1" data-parsoid="{}"><h1 id="1"> 1 </h1>
  <p>a</p>
  
 -<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"dsr":[9,60,0,0],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"x\n== 1.1 ==\nb\n==1.2==\nc\n===1.2.1===\nd"}},"i":0}},"\n"]}'>x</p><span about="#mwt1">
 -</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="1.1"> 1.1 </h2><span about="#mwt1">
 +<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"dsr":[9,60,0,0],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"x\n==1.1==\nb\n==1.2==\nc\n===1.2.1===\nd"}},"i":0}},"\n"]}'>x</p><span about="#mwt1">
 +</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="1.1">1.1</h2><span about="#mwt1">
  </span><p about="#mwt1">b</p><span about="#mwt1">
  </span></section><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="1.2">1.2</h2><span about="#mwt1">
  </span><p about="#mwt1">c</p><span about="#mwt1">
  </span><section data-mw-section-id="-1" about="#mwt1"><h3 about="#mwt1" id="1.2.1">1.2.1</h3><span about="#mwt1">
  </span><p about="#mwt1">d</p><span about="#mwt1">
 -</span></section></section></section><section data-mw-section-id="5"><h1 id="2"> 2 </h1>
 +</span></section></section></section><section data-mw-section-id="5"><h1 id="2">2</h1>
  <p>e</p></section>
  !! end
  
@@@ -31921,7 -30210,7 +31944,7 @@@ parsoid=
  a
  
  {{echo|
 -= 1 =
 +=1=
  b
  }}
  
  <section data-mw-section-id="-1"></section><section data-mw-section-id="-2"><div data-parsoid='{"stx":"html"}'>
  <p>a</p>
  
 -<span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n= 1 =\nb\n"}},"i":0}},"\n\nc\n"]}'>
 -</span><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="1"> 1 </h1><span about="#mwt1">
 +<span about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n=1=\nb\n"}},"i":0}},"\n\nc\n"]}'>
 +</span><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="1">1</h1><span about="#mwt1">
  </span><p about="#mwt1">b
  </p><span about="#mwt1">
  
@@@ -31951,32 -30240,32 +31974,32 @@@ parsoid=
    "wrapSections": true
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
  {{echo|1=
 -= 2 =
 +=2=
  b
 -== 2.1 ==
 +==2.1==
  c
  }}
  
  d
  
 -= 3 =
 +=3=
  e
  !! html/parsoid
 -<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="0"></section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -</section><section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="2" data-parsoid='{"dsr":[9,45,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"= 2 =\nb\n== 2.1 ==\nc"}},"i":0}},"\n\nd\n\n"]}'> 2 </h1><span about="#mwt1">
 +</section><section data-mw-section-id="-1"><h1 about="#mwt1" typeof="mw:Transclusion" id="2" data-parsoid='{"dsr":[9,45,null,null],"pi":[[{"k":"1","named":true,"spc":["","","\n","\n"]}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"=2=\nb\n==2.1==\nc"}},"i":0}},"\n\nd\n\n"]}'>2</h1><span about="#mwt1">
  </span><p about="#mwt1">b</p><span about="#mwt1">
 -</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="2.1"> 2.1 </h2><span about="#mwt1">
 +</span><section data-mw-section-id="-1" about="#mwt1"><h2 about="#mwt1" id="2.1">2.1</h2><span about="#mwt1">
  </span><p about="#mwt1">c</p><span about="#mwt1">
  
  </span><p about="#mwt1">d</p><span about="#mwt1">
  
 -</span></section></section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
 +</span></section></section><section data-mw-section-id="4"><h1 id="3">3</h1>
  <p>e</p></section>
  !! end
  
@@@ -31994,31 -30283,31 +32017,31 @@@ parsoid=
    "modes": ["wt2html", "wt2wt"]
  }
  !! wikitext
 -= 1 =
 +=1=
  a
  
  {{echo|1=
 -== 1.2 ==
 +==1.2==
  b
 -= 2 =
 +=2=
  c
  }}
  
  d
  
 -= 3 =
 +=3=
  e
  !! html/parsoid
 -<section data-mw-section-id="0"></section><section data-mw-section-id="1" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["= 1 =\na\n\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.2 ==\nb\n= 2 =\nc"}},"i":0}},"\n\nd\n\n"]}'><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="0"></section><section data-mw-section-id="1" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["=1=\na\n\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.2==\nb\n=2=\nc"}},"i":0}},"\n\nd\n\n"]}'><h1 id="1">1</h1>
  <p>a</p>
  
 -<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"== 1.2 ==\nb\n= 2 =\nc"}},"i":0}}]}'> 1.2 </h2><span about="#mwt1">
 +<section data-mw-section-id="-1"><h2 about="#mwt1" typeof="mw:Transclusion" id="1.2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"==1.2==\nb\n=2=\nc"}},"i":0}}]}'>1.2</h2><span about="#mwt1">
  </span><p about="#mwt1">b</p><span about="#mwt1">
 -</span></section></section><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="2"> 2 </h1><span about="#mwt1">
 +</span></section></section><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1" id="2">2</h1><span about="#mwt1">
  </span><p about="#mwt1">c</p>
  
  <p>d</p>
 -</section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="3"> 3 </h1>
 +</section><section data-mw-section-id="4" data-parsoid="{}"><h1 id="3">3</h1>
  <p>e</p></section>
  !! end
  
@@@ -32032,39 -30321,39 +32055,39 @@@ parsoid=
  foo
  
  <div style="border:1px solid red;">
 -= 1 =
 +=1=
  a
  
 -== 1.1 ==
 +==1.1==
  b
  
 -= 2 =
 +=2=
  c
  </div>
  
 -= 3 =
 +=3=
  d
  
 -== 3.1 ==
 +==3.1==
  e
  !! html/parsoid
  <section data-mw-section-id="-1"><p>foo</p>
  
  </section><section data-mw-section-id="-2"><div style="border:1px solid red;">
 -<section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +<section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -<section data-mw-section-id="2"><h2 id="1.1"> 1.1 </h2>
 +<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
  <p>b</p>
  
 -</section></section><section data-mw-section-id="-1"><h1 id="2"> 2 </h1>
 +</section></section><section data-mw-section-id="-1"><h1 id="2">2</h1>
  <p>c</p>
  </section></div>
  
 -</section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
 +</section><section data-mw-section-id="4"><h1 id="3">3</h1>
  <p>d</p>
  
 -<section data-mw-section-id="5"><h2 id="3.1"> 3.1 </h2>
 +<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
  <p>e</p>
  </section></section>
  !! end
@@@ -32078,44 -30367,44 +32101,44 @@@ parsoid=
  !! wikitext
  foo
  
 -= 1 =
 +=1=
  a
  <div style="border:1px solid red;">
  b
  
 -== 1.1 ==
 +==1.1==
  c
  
 -= 2 =
 +=2=
  d
  </div>
  e
  
 -= 3 =
 +=3=
  f
  
 -== 3.1 ==
 +==3.1==
  g
  !! html/parsoid
  <section data-mw-section-id="0"><p>foo</p>
  
 -</section><section data-mw-section-id="-1"><h1 id="1"> 1 </h1>
 +</section><section data-mw-section-id="-1"><h1 id="1">1</h1>
  <p>a</p>
  </section><section data-mw-section-id="-2"><div style="border:1px solid red;">
  <p>b</p>
  
 -<section data-mw-section-id="2"><h2 id="1.1"> 1.1 </h2>
 +<section data-mw-section-id="2"><h2 id="1.1">1.1</h2>
  <p>c</p>
  
 -</section><section data-mw-section-id="-1"><h1 id="2"> 2 </h1>
 +</section><section data-mw-section-id="-1"><h1 id="2">2</h1>
  <p>d</p>
  </section></div>
  <p>e</p>
  
 -</section><section data-mw-section-id="4"><h1 id="3"> 3 </h1>
 +</section><section data-mw-section-id="4"><h1 id="3">3</h1>
  <p>f</p>
  
 -<section data-mw-section-id="5"><h2 id="3.1"> 3.1 </h2>
 +<section data-mw-section-id="5"><h2 id="3.1">3.1</h2>
  <p>g</p>
  </section></section>
  !! end
  
  <h1>a</h1>
  
 -= b =
 +=b=
  
  <h1>c</h1>
  
 -= d =
 +=d=
  !! html/parsoid
  <section data-mw-section-id="0"><p>foo</p>
  
  <h1 id="a" data-parsoid='{"stx":"html"}'>a</h1>
  
 -</section><section data-mw-section-id="1"><h1 id="b"> b </h1>
 +</section><section data-mw-section-id="1"><h1 id="b">b</h1>
  
  <h1 id="c" data-parsoid='{"stx":"html"}'>c</h1>
  
 -</section><section data-mw-section-id="2"><h1 id="d"> d </h1></section>
 +</section><section data-mw-section-id="2"><h1 id="d">d</h1></section>
  !! end
  
  !! test
@@@ -32157,18 -30446,18 +32180,18 @@@ parsoid=
  !! wikitext
  
  <!-- this is a comment, presumably significant to editors -->
 -= 1 =
 +=1=
  a
  
 -= 2 =
 +=2=
  b
  !! html/parsoid
  <section data-mw-section-id="0" data-parsoid="{}">
  <!-- this is a comment, presumably significant to editors -->
 -</section><section data-mw-section-id="1"><h1 id="1"> 1 </h1>
 +</section><section data-mw-section-id="1"><h1 id="1">1</h1>
  <p>a</p>
  
 -</section><section data-mw-section-id="2"><h1 id="2"> 2 </h1>
 +</section><section data-mw-section-id="2"><h1 id="2">2</h1>
  <p>b</p></section>
  !! end
  
@@@ -32181,260 -30470,15 +32204,260 @@@ parsoid=
  !! wikitext
  foo
  {{echo|<div>
 -== a ==
 -== b ==
 +==a==
 +==b==
  </div>
  }}
  !! html/parsoid
  <section data-mw-section-id="-1"><p>foo</p>
 -</section><section data-mw-section-id="-2"><div about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>\n== a ==\n== b ==\n&lt;/div>\n"}},"i":0}}]}'>
 -<section data-mw-section-id="-1"><h2 id="a"> a </h2>
 -</section><section data-mw-section-id="-1"><h2 id="b"> b </h2>
 +</section><section data-mw-section-id="-2"><div about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div>\n==a==\n==b==\n&lt;/div>\n"}},"i":0}}]}'>
 +<section data-mw-section-id="-1"><h2 id="a">a</h2>
 +</section><section data-mw-section-id="-1"><h2 id="b">b</h2>
  </section></div><span about="#mwt1">
  </span></section>
  !! end
 +
 +##########################################################################
 +Tests demonstrating white-space insensitivity in input wikitext
 +for wikitext headings, wikitext list items, and wikitext table captions,
 +headings, and cells. HTML versions of the same should preserve whitespace.
 +##########################################################################
 +!! test
 +Trim whitespace in wikitext headings, list items, table captions, headings, and cells
 +!! options
 +parsoid={
 +      "modes": ["wt2html"],
 +      "preserveIEW": true
 +}
 +!! wikitext
 +__NOTOC__
 +==    <!--c1-->  <!--c2--> Spaces   <!--c3--> <!--c4-->  ==
 +==            <!--c1-->       <!--c2--> Tabs          <!--c3--><!--c4-->      ==
 +== <!--Headings with fallback ids--> Личная жизнь ==
 +*     <!--c1-->   <!--c2-->  List item <!--c3--> <!--c4-->
 +; <!--term to define--> term : <!--term's definition--> definition
 +{|
 +|+ <!--c1--> <!--c2--> Table Caption <!--c3--> <!--c4-->
 +|-
 +!  <!--c1--> <!--c2--> Table Heading 1 <!--c3--> <!--c4--> !!   Table Heading 2 <!--c5-->
 +|-
 +| <!--c1--> <!--c2--> Table Cell 1 <!--c3--> <!--c4--> ||   Table Cell 2 <!--c5-->
 +|-
 +| class="foo" || <!--c1--> <!--c2--> Table Cell 3 <!--c3--> <!--c4-->
 +|-
 +| <!--c1--> testing [[one|two]] <!--c2--> | <!--c3--> some content
 +|}
 +: {|
 +  |  <!--c1--> <!--c2--> Table Cell 1 <!--c3--> <!--c4--> ||   Table Cell 2 <!--c5-->
 +  |} foo   <!--c1-->
 +!! html/php+tidy
 +<h2><span class="mw-headline" id="Spaces">Spaces</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Spaces">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<h2><span class="mw-headline" id="Tabs">Tabs</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Tabs">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<h2><span class="mw-headline" id=".D0.9B.D0.B8.D1.87.D0.BD.D0.B0.D1.8F_.D0.B6.D0.B8.D0.B7.D0.BD.D1.8C">Личная жизнь</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=3" title="Edit section: Личная жизнь">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 +<ul><li>List item</li></ul>
 +<dl><dt>term&#160;</dt>
 +<dd>definition</dd></dl>
 +<table>
 +<caption>Table Caption
 +</caption>
 +<tbody><tr>
 +<th>Table Heading 1</th>
 +<th>Table Heading 2
 +</th></tr>
 +<tr>
 +<td>Table Cell 1</td>
 +<td>Table Cell 2
 +</td></tr>
 +<tr>
 +<td>class="foo"</td>
 +<td>Table Cell 3
 +</td></tr>
 +<tr>
 +<td>testing <a href="/index.php?title=One&amp;action=edit&amp;redlink=1" class="new" title="One (page does not exist)">two</a>  |  some content
 +</td></tr></tbody></table>
 +<dl><dd><table>
 +<tbody><tr>
 +<td>Table Cell 1</td>
 +<td>Table Cell 2
 +</td></tr></tbody></table> foo</dd></dl>
 +!! html/parsoid
 +<meta property="mw:PageProp/notoc">
 +<h2 id="Spaces"><!--c1--><!--c2-->Spaces<!--c3--><!--c4--></h2>
 +<h2 id="Tabs"><!--c1--><!--c2-->Tabs<!--c3--><!--c4--></h2>
 +<h2 id="Личная_жизнь"><span id=".D0.9B.D0.B8.D1.87.D0.BD.D0.B0.D1.8F_.D0.B6.D0.B8.D0.B7.D0.BD.D1.8C" typeof="mw:FallbackId"></span><!--Headings with fallback ids-->Личная жизнь</h2>
 +<ul><li><!--c1--><!--c2-->List item<!--c3--><!--c4--></li></ul>
 +<dl><dt><!--term to define-->term&nbsp;</dt><dd><!--term's definition-->definition</dd></dl>
 +<table>
 +<caption><!--c1--><!--c2-->Table Caption<!--c3--><!--c4--></caption>
 +<tbody><tr>
 +<th><!--c1--><!--c2-->Table Heading 1<!--c3--><!--c4--></th><th>Table Heading 2<!--c5--></th></tr>
 +<tr>
 +<td><!--c1--><!--c2-->Table Cell 1<!--c3--><!--c4--></td><td>Table Cell 2<!--c5--></td></tr>
 +<tr>
 +<td>class="foo"</td><td><!--c1--><!--c2-->Table Cell 3<!--c3--><!--c4--></td></tr>
 +<tr>
 +<td><!--c1-->testing <a rel="mw:WikiLink" href="./One" title="One">two</a> <!--c2--> | <!--c3--> some content</td></tr>
 +</tbody></table>
 +<dl><dd><table>
 +  <tbody><tr><td><!--c1--><!--c2-->Table Cell 1<!--c3--><!--c4--></td><td>Table Cell 2<!--c5--></td></tr>
 +  </tbody></table> foo<!--c1--></dd></dl>
 +!! end
 +
 +# Looks like <caption> is not accepted in HTML
 +!! test
 +Do not trim whitespace in HTML headings, list items, table captions, headings, and cells
 +!! options
 +parsoid={
 +      "modes": ["wt2html"],
 +      "preserveIEW": true
 +}
 +!! wikitext
 +__NOTOC__
 +<h2>    <!--c1-->   <!--c2--> Heading    <!--c3--> <!--c4-->  </h2>
 +<ul><li>     <!--c1-->   <!--c2-->  List item <!--c3--> <!--c4-->  </li></ul>
 +<table>
 +<tr><th> <!--c1--> <!--c2--> Table Heading <!--c3--> <!--c4--> <th></tr>
 +<tr><td> <!--c1--> <!--c2--> Table Cell <!--c3--> <!--c4--> <th></tr>
 +</table>
 +!! html/php+tidy
 +<h2><span class="mw-headline" id="Heading">        Heading       </span></h2>
 +<ul><li>          List item    </li></ul>
 +<table>
 +<tbody><tr><th>   Table Heading   </th><th></th></tr>
 +<tr><td>   Table Cell   </td><th></th></tr>
 +</tbody></table>
 +!! html/parsoid
 +<meta property="mw:PageProp/notoc"/>
 +<h2 id="Heading">    <!--c1-->   <!--c2--> Heading    <!--c3--> <!--c4-->  </h2>
 +<ul><li>     <!--c1-->   <!--c2-->  List item <!--c3--> <!--c4-->  </li></ul>
 +<table>
 +<tbody><tr><th> <!--c1--> <!--c2--> Table Heading <!--c3--> <!--c4--> </th><th></th></tr>
 +<tr><td> <!--c1--> <!--c2--> Table Cell <!--c3--> <!--c4--> </td><th></th></tr>
 +</tbody></table>
 +!! end
 +
 +!! test
 +Do not trim whitespace in links and quotes
 +!! options
 +parsoid={
 +      "modes": ["wt2html"],
 +      "preserveIEW": true
 +}
 +!! wikitext
 +foo ''  <!--c1--> italic <!--c2-->   '' and '''  <!--c3-->  bold  <!--c4-->  '''
 +[[Foo|  some text  ]]
 +!! html/php+tidy
 +<p>foo <i>   italic    </i> and <b>    bold    </b>
 +<a href="/wiki/Foo" title="Foo">  some text  </a>
 +</p>
 +!! html/parsoid
 +<p>foo <i>  <!--c1--> italic <!--c2-->   </i> and <b>  <!--c3-->  bold  <!--c4-->  </b>
 +<a rel="mw:WikiLink" href="./Foo" title="Foo">  some text  </a></p>
 +!! end
 +
 +!! test
 +Remove p tags surrounding a single element in a figcaption
 +!! options
 +parsoid=html2wt
 +!! wikitext
 +[[File:Foobar.jpg|right|200x200px|Caption]]
 +!! html/parsoid
 +<figure class="mw-halign-right" typeof="mw:Image"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="23" width="200"/></a><figcaption><p>Caption</p></figcaption></figure>
 +!! end
 +
 +!! test
 +Selser preserves lack of newline before list and allows newline after the list
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "scrubWikitext": true,
 +  "changes": [
 +    [ "ul", "after", "<p>footer</p>" ]
 +  ]
 +}
 +!! wikitext
 +header
 +*foo
 +*bar
 +!! wikitext/edited
 +header
 +*foo
 +*bar
 +
 +footer
 +!! end
 +
 +
 +!! test
 +Selser does not introduce newlines between unedited paragraph preceding the list
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "changes": [
 +    [ "table tbody tr td p:last-child", "empty" ]
 +  ]
 +}
 +!! wikitext
 +{|
 +|
 +header
 +*foo
 +*bar
 +footer
 +|}
 +!! wikitext/edited
 +{|
 +|
 +header
 +*foo
 +*bar
 +
 +|}
 +!! end
 +
 +!! test
 +Selser does not introduce newlines between unedited paragraph following the list
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "changes": [
 +    [ "table tbody tr td p:first-child", "empty" ]
 +  ]
 +}
 +!! wikitext
 +{|
 +|
 +header
 +*foo
 +*bar
 +footer
 +|}
 +!! wikitext/edited
 +{|
 +|
 +
 +*foo
 +*bar
 +footer
 +|}
 +!! end
 +
 +!! test
 +Remove a list item but do not insert newline above list
 +!! options
 +parsoid={
 +  "modes": ["selser"],
 +  "changes": [
 +     [ "ul li:last-child", "remove" ]
 +  ]
 +}
 +!! wikitext
 +header
 +*foo
 +*bar
 +footer
 +!! wikitext/edited
 +header
 +*foo
 +footer
 +!! end