X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Ftidy%2FBalancer.php;h=e57063377877d221c107f0a067c3705ec9d1e497;hp=fbe92702df70d7b334b82ab4ce3f1d16d9973c35;hb=08edb27f6ce31c676660a4ef89b87da79bde2cc2;hpb=5cb794e3d9e55ee3fa71ddaca05be4e4225f84f1 diff --git a/includes/tidy/Balancer.php b/includes/tidy/Balancer.php index fbe92702df..e570633778 100644 --- a/includes/tidy/Balancer.php +++ b/includes/tidy/Balancer.php @@ -1669,13 +1669,11 @@ class BalanceActiveFormattingElements { $this->addToNoahList( $b ); } - // @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong /** * Reconstruct the active formatting elements. * @param BalanceStack $stack The open elements stack * @see https://html.spec.whatwg.org/multipage/syntax.html#reconstruct-the-active-formatting-elements */ - // @codingStandardsIgnoreEnd public function reconstruct( $stack ) { $entry = $this->tail; // If there are no entries in the list of active formatting elements, @@ -2054,73 +2052,73 @@ class Balancer { return true; } elseif ( $token === 'tag' ) { switch ( $value ) { - case 'font': - if ( isset( $attribs['color'] ) - || isset( $attribs['face'] ) - || isset( $attribs['size'] ) - ) { - break; - } - // otherwise, fall through - case 'b': - case 'big': - case 'blockquote': - case 'body': - case 'br': - case 'center': - case 'code': - case 'dd': - case 'div': - case 'dl': - case 'dt': - case 'em': - case 'embed': - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - case 'head': - case 'hr': - case 'i': - case 'img': - case 'li': - case 'listing': - case 'menu': - case 'meta': - case 'nobr': - case 'ol': - case 'p': - case 'pre': - case 'ruby': - case 's': - case 'small': - case 'span': - case 'strong': - case 'strike': - case 'sub': - case 'sup': - case 'table': - case 'tt': - case 'u': - case 'ul': - case 'var': - if ( $this->fragmentContext ) { - break; - } - while ( true ) { - $this->stack->pop(); - $node = $this->stack->currentNode; - if ( - $node->isMathmlTextIntegrationPoint() || - $node->isHtmlIntegrationPoint() || - $node->isHtml() + case 'font': + if ( isset( $attribs['color'] ) + || isset( $attribs['face'] ) + || isset( $attribs['size'] ) ) { break; } - } - return $this->insertToken( $token, $value, $attribs, $selfClose ); + // otherwise, fall through + case 'b': + case 'big': + case 'blockquote': + case 'body': + case 'br': + case 'center': + case 'code': + case 'dd': + case 'div': + case 'dl': + case 'dt': + case 'em': + case 'embed': + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + case 'head': + case 'hr': + case 'i': + case 'img': + case 'li': + case 'listing': + case 'menu': + case 'meta': + case 'nobr': + case 'ol': + case 'p': + case 'pre': + case 'ruby': + case 's': + case 'small': + case 'span': + case 'strong': + case 'strike': + case 'sub': + case 'sup': + case 'table': + case 'tt': + case 'u': + case 'ul': + case 'var': + if ( $this->fragmentContext ) { + break; + } + while ( true ) { + $this->stack->pop(); + $node = $this->stack->currentNode; + if ( + $node->isMathmlTextIntegrationPoint() || + $node->isHtmlIntegrationPoint() || + $node->isHtml() + ) { + break; + } + } + return $this->insertToken( $token, $value, $attribs, $selfClose ); } // "Any other start tag" $adjusted = ( $this->fragmentContext && $this->stack->length() === 1 ) ? @@ -2272,56 +2270,56 @@ class Balancer { } if ( $node->isHtml() ) { switch ( $node->localName ) { - case 'select': - $stackLength = $this->stack->length(); - for ( $j = $i + 1; $j < $stackLength - 1; $j++ ) { - $ancestor = $this->stack->node( $stackLength - $j - 1 ); - if ( $ancestor->isHtmlNamed( 'template' ) ) { - break; + case 'select': + $stackLength = $this->stack->length(); + for ( $j = $i + 1; $j < $stackLength - 1; $j++ ) { + $ancestor = $this->stack->node( $stackLength - $j - 1 ); + if ( $ancestor->isHtmlNamed( 'template' ) ) { + break; + } + if ( $ancestor->isHtmlNamed( 'table' ) ) { + $this->switchMode( 'inSelectInTableMode' ); + return; + } } - if ( $ancestor->isHtmlNamed( 'table' ) ) { - $this->switchMode( 'inSelectInTableMode' ); - return; - } - } - $this->switchMode( 'inSelectMode' ); - return; - case 'tr': - $this->switchMode( 'inRowMode' ); - return; - case 'tbody': - case 'tfoot': - case 'thead': - $this->switchMode( 'inTableBodyMode' ); - return; - case 'caption': - $this->switchMode( 'inCaptionMode' ); - return; - case 'colgroup': - $this->switchMode( 'inColumnGroupMode' ); - return; - case 'table': - $this->switchMode( 'inTableMode' ); - return; - case 'template': - $this->switchMode( - array_slice( $this->templateInsertionModes, -1 )[0] - ); - return; - case 'body': - $this->switchMode( 'inBodyMode' ); - return; - // OMITTED: - // OMITTED: - // OMITTED: - default: - if ( !$last ) { - // OMITTED: - if ( $node->isA( BalanceSets::$tableCellSet ) ) { - $this->switchMode( 'inCellMode' ); - return; + $this->switchMode( 'inSelectMode' ); + return; + case 'tr': + $this->switchMode( 'inRowMode' ); + return; + case 'tbody': + case 'tfoot': + case 'thead': + $this->switchMode( 'inTableBodyMode' ); + return; + case 'caption': + $this->switchMode( 'inCaptionMode' ); + return; + case 'colgroup': + $this->switchMode( 'inColumnGroupMode' ); + return; + case 'table': + $this->switchMode( 'inTableMode' ); + return; + case 'template': + $this->switchMode( + array_slice( $this->templateInsertionModes, -1 )[0] + ); + return; + case 'body': + $this->switchMode( 'inBodyMode' ); + return; + // OMITTED: + // OMITTED: + // OMITTED: + default: + if ( !$last ) { + // OMITTED: + if ( $node->isA( BalanceSets::$tableCellSet ) ) { + $this->switchMode( 'inCellMode' ); + return; + } } - } } } if ( $last ) { @@ -2380,52 +2378,52 @@ class Balancer { // Fall through to handle non-whitespace below. } elseif ( $token === 'tag' ) { switch ( $value ) { - case 'meta': - // OMITTED: in a full HTML parser, this might change the encoding. - // falls through - // OMITTED: - case 'base': - case 'basefont': - case 'bgsound': - case 'link': - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - return true; - // OMITTED: - // OMITTED: <noscript> - case 'noframes': - case 'style': - return $this->parseRawText( $value, $attribs ); - // OMITTED: <script> - case 'template': - $this->stack->insertHTMLElement( $value, $attribs ); - $this->afe->insertMarker(); - // OMITTED: frameset_ok - $this->switchMode( 'inTemplateMode' ); - $this->templateInsertionModes[] = $this->parseMode; - return true; - // OMITTED: <head> + case 'meta': + // OMITTED: in a full HTML parser, this might change the encoding. + // falls through + // OMITTED: <html> + case 'base': + case 'basefont': + case 'bgsound': + case 'link': + $this->stack->insertHTMLElement( $value, $attribs ); + $this->stack->pop(); + return true; + // OMITTED: <title> + // OMITTED: <noscript> + case 'noframes': + case 'style': + return $this->parseRawText( $value, $attribs ); + // OMITTED: <script> + case 'template': + $this->stack->insertHTMLElement( $value, $attribs ); + $this->afe->insertMarker(); + // OMITTED: frameset_ok + $this->switchMode( 'inTemplateMode' ); + $this->templateInsertionModes[] = $this->parseMode; + return true; + // OMITTED: <head> } } elseif ( $token === 'endtag' ) { switch ( $value ) { - // OMITTED: <head> - // OMITTED: <body> - // OMITTED: <html> - case 'br': - break; // handle at the bottom of the function - case 'template': - if ( $this->stack->indexOf( $value ) < 0 ) { - return true; // Ignore the token. - } - $this->stack->generateImpliedEndTags( null, true /* thorough */ ); - $this->stack->popTag( $value ); - $this->afe->clearToMarker(); - array_pop( $this->templateInsertionModes ); - $this->resetInsertionMode(); - return true; - default: - // ignore any other end tag - return true; + // OMITTED: <head> + // OMITTED: <body> + // OMITTED: <html> + case 'br': + break; // handle at the bottom of the function + case 'template': + if ( $this->stack->indexOf( $value ) < 0 ) { + return true; // Ignore the token. + } + $this->stack->generateImpliedEndTags( null, true /* thorough */ ); + $this->stack->popTag( $value ); + $this->afe->clearToMarker(); + array_pop( $this->templateInsertionModes ); + $this->resetInsertionMode(); + return true; + default: + // ignore any other end tag + return true; } } elseif ( $token === 'comment' ) { $this->stack->insertComment( $value ); @@ -2451,505 +2449,505 @@ class Balancer { return true; } elseif ( $token === 'tag' ) { switch ( $value ) { - // OMITTED: <html> - case 'base': - case 'basefont': - case 'bgsound': - case 'link': - case 'meta': - case 'noframes': - // OMITTED: <script> - case 'style': - case 'template': - // OMITTED: <title> - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); - // OMITTED: <body> - // OMITTED: <frameset> - - case 'address': - case 'article': - case 'aside': - case 'blockquote': - case 'center': - case 'details': - case 'dialog': - case 'dir': - case 'div': - case 'dl': - case 'fieldset': - case 'figcaption': - case 'figure': - case 'footer': - case 'header': - case 'hgroup': - case 'main': - case 'nav': - case 'ol': - case 'p': - case 'section': - case 'summary': - case 'ul': - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; - - case 'menu': - if ( $this->stack->inButtonScope( "p" ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { - $this->stack->pop(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + // OMITTED: <html> + case 'base': + case 'basefont': + case 'bgsound': + case 'link': + case 'meta': + case 'noframes': + // OMITTED: <script> + case 'style': + case 'template': + // OMITTED: <title> + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + // OMITTED: <body> + // OMITTED: <frameset> - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - if ( $this->stack->currentNode->isA( BalanceSets::$headingSet ) ) { - $this->stack->pop(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + case 'address': + case 'article': + case 'aside': + case 'blockquote': + case 'center': + case 'details': + case 'dialog': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'figcaption': + case 'figure': + case 'footer': + case 'header': + case 'hgroup': + case 'main': + case 'nav': + case 'ol': + case 'p': + case 'section': + case 'summary': + case 'ul': + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'pre': - case 'listing': - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - $this->ignoreLinefeed = true; - // OMITTED: frameset_ok - return true; + case 'menu': + if ( $this->stack->inButtonScope( "p" ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { + $this->stack->pop(); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'form': - if ( - $this->formElementPointer && - $this->stack->indexOf( 'template' ) < 0 - ) { - return true; // in a form, not in a template. - } - if ( $this->stack->inButtonScope( "p" ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $elt = $this->stack->insertHTMLElement( $value, $attribs ); - if ( $this->stack->indexOf( 'template' ) < 0 ) { - $this->formElementPointer = $elt; - } - return true; + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + if ( $this->stack->currentNode->isA( BalanceSets::$headingSet ) ) { + $this->stack->pop(); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'li': - // OMITTED: frameset_ok - foreach ( $this->stack as $node ) { - if ( $node->isHtmlNamed( 'li' ) ) { - $this->inBodyMode( 'endtag', 'li' ); - break; + case 'pre': + case 'listing': + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); } + $this->stack->insertHTMLElement( $value, $attribs ); + $this->ignoreLinefeed = true; + // OMITTED: frameset_ok + return true; + + case 'form': if ( - $node->isA( BalanceSets::$specialSet ) && - !$node->isA( BalanceSets::$addressDivPSet ) + $this->formElementPointer && + $this->stack->indexOf( 'template' ) < 0 ) { - break; + return true; // in a form, not in a template. } - } - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; - - case 'dd': - case 'dt': - // OMITTED: frameset_ok - foreach ( $this->stack as $node ) { - if ( $node->isHtmlNamed( 'dd' ) ) { - $this->inBodyMode( 'endtag', 'dd' ); - break; + if ( $this->stack->inButtonScope( "p" ) ) { + $this->inBodyMode( 'endtag', 'p' ); } - if ( $node->isHtmlNamed( 'dt' ) ) { - $this->inBodyMode( 'endtag', 'dt' ); - break; + $elt = $this->stack->insertHTMLElement( $value, $attribs ); + if ( $this->stack->indexOf( 'template' ) < 0 ) { + $this->formElementPointer = $elt; } - if ( - $node->isA( BalanceSets::$specialSet ) && - !$node->isA( BalanceSets::$addressDivPSet ) - ) { - break; + return true; + + case 'li': + // OMITTED: frameset_ok + foreach ( $this->stack as $node ) { + if ( $node->isHtmlNamed( 'li' ) ) { + $this->inBodyMode( 'endtag', 'li' ); + break; + } + if ( + $node->isA( BalanceSets::$specialSet ) && + !$node->isA( BalanceSets::$addressDivPSet ) + ) { + break; + } } - } - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - // OMITTED: <plaintext> + case 'dd': + case 'dt': + // OMITTED: frameset_ok + foreach ( $this->stack as $node ) { + if ( $node->isHtmlNamed( 'dd' ) ) { + $this->inBodyMode( 'endtag', 'dd' ); + break; + } + if ( $node->isHtmlNamed( 'dt' ) ) { + $this->inBodyMode( 'endtag', 'dt' ); + break; + } + if ( + $node->isA( BalanceSets::$specialSet ) && + !$node->isA( BalanceSets::$addressDivPSet ) + ) { + break; + } + } + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'button': - if ( $this->stack->inScope( 'button' ) ) { - $this->inBodyMode( 'endtag', 'button' ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - } - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + // OMITTED: <plaintext> - case 'a': - $activeElement = $this->afe->findElementByTag( 'a' ); - if ( $activeElement ) { - $this->inBodyMode( 'endtag', 'a' ); - if ( $this->afe->isInList( $activeElement ) ) { - $this->afe->remove( $activeElement ); - // Don't flatten here, since when we fall - // through below we might foster parent - // the new <a> tag inside this one. - $this->stack->removeElement( $activeElement, false ); + case 'button': + if ( $this->stack->inScope( 'button' ) ) { + $this->inBodyMode( 'endtag', 'button' ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); } - } - // Falls through - case 'b': - case 'big': - case 'code': - case 'em': - case 'font': - case 'i': - case 's': - case 'small': - case 'strike': - case 'strong': - case 'tt': - case 'u': - $this->afe->reconstruct( $this->stack ); - $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) ); - return true; - - case 'nobr': - $this->afe->reconstruct( $this->stack ); - if ( $this->stack->inScope( 'nobr' ) ) { - $this->inBodyMode( 'endtag', 'nobr' ); $this->afe->reconstruct( $this->stack ); - } - $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) ); - return true; - - case 'applet': - case 'marquee': - case 'object': - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->afe->insertMarker(); - // OMITTED: frameset_ok - return true; + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'table': - // The document is never in "quirks mode"; see simplifications - // above. - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - // OMITTED: frameset_ok - $this->switchMode( 'inTableMode' ); - return true; + case 'a': + $activeElement = $this->afe->findElementByTag( 'a' ); + if ( $activeElement ) { + $this->inBodyMode( 'endtag', 'a' ); + if ( $this->afe->isInList( $activeElement ) ) { + $this->afe->remove( $activeElement ); + // Don't flatten here, since when we fall + // through below we might foster parent + // the new <a> tag inside this one. + $this->stack->removeElement( $activeElement, false ); + } + } + // Falls through + case 'b': + case 'big': + case 'code': + case 'em': + case 'font': + case 'i': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + $this->afe->reconstruct( $this->stack ); + $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) ); + return true; - case 'area': - case 'br': - case 'embed': - case 'img': - case 'keygen': - case 'wbr': - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - // OMITTED: frameset_ok - return true; + case 'nobr': + $this->afe->reconstruct( $this->stack ); + if ( $this->stack->inScope( 'nobr' ) ) { + $this->inBodyMode( 'endtag', 'nobr' ); + $this->afe->reconstruct( $this->stack ); + } + $this->afe->push( $this->stack->insertHTMLElement( $value, $attribs ) ); + return true; - case 'input': - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - // OMITTED: frameset_ok - // (hence we don't need to examine the tag's "type" attribute) - return true; + case 'applet': + case 'marquee': + case 'object': + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->afe->insertMarker(); + // OMITTED: frameset_ok + return true; - case 'param': - case 'source': - case 'track': - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - return true; + case 'table': + // The document is never in "quirks mode"; see simplifications + // above. + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + $this->stack->insertHTMLElement( $value, $attribs ); + // OMITTED: frameset_ok + $this->switchMode( 'inTableMode' ); + return true; - case 'hr': - if ( $this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'endtag', 'p' ); - } - if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { + case 'area': + case 'br': + case 'embed': + case 'img': + case 'keygen': + case 'wbr': + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); $this->stack->pop(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - return true; - - case 'image': - // warts! - return $this->inBodyMode( $token, 'img', $attribs, $selfClose ); - - case 'textarea': - $this->stack->insertHTMLElement( $value, $attribs ); - $this->ignoreLinefeed = true; - $this->inRCDATA = $value; // emulate rcdata tokenizer mode - // OMITTED: frameset_ok - return true; - - // OMITTED: <xmp> - // OMITTED: <iframe> - // OMITTED: <noembed> - // OMITTED: <noscript> - - case 'select': - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - switch ( $this->parseMode ) { - case 'inTableMode': - case 'inCaptionMode': - case 'inTableBodyMode': - case 'inRowMode': - case 'inCellMode': - $this->switchMode( 'inSelectInTableMode' ); + // OMITTED: frameset_ok return true; - default: - $this->switchMode( 'inSelectMode' ); + + case 'input': + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->stack->pop(); + // OMITTED: frameset_ok + // (hence we don't need to examine the tag's "type" attribute) return true; - } - case 'optgroup': - case 'option': - if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { - $this->inBodyMode( 'endtag', 'option' ); - } - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + case 'param': + case 'source': + case 'track': + $this->stack->insertHTMLElement( $value, $attribs ); + $this->stack->pop(); + return true; - case 'menuitem': - if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { + case 'hr': + if ( $this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'endtag', 'p' ); + } + if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { + $this->stack->pop(); + } + $this->stack->insertHTMLElement( $value, $attribs ); $this->stack->pop(); - } - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + return true; - case 'rb': - case 'rtc': - if ( $this->stack->inScope( 'ruby' ) ) { - $this->stack->generateImpliedEndTags(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + case 'image': + // warts! + return $this->inBodyMode( $token, 'img', $attribs, $selfClose ); - case 'rp': - case 'rt': - if ( $this->stack->inScope( 'ruby' ) ) { - $this->stack->generateImpliedEndTags( 'rtc' ); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; + case 'textarea': + $this->stack->insertHTMLElement( $value, $attribs ); + $this->ignoreLinefeed = true; + $this->inRCDATA = $value; // emulate rcdata tokenizer mode + // OMITTED: frameset_ok + return true; - case 'math': - $this->afe->reconstruct( $this->stack ); - // We skip the spec's "adjust MathML attributes" and - // "adjust foreign attributes" steps, since the browser will - // do this later when it parses the output and it doesn't affect - // balancing. - $this->stack->insertForeignElement( - BalanceSets::MATHML_NAMESPACE, $value, $attribs - ); - if ( $selfClose ) { - // emit explicit </math> tag. - $this->stack->pop(); - } - return true; + // OMITTED: <xmp> + // OMITTED: <iframe> + // OMITTED: <noembed> + // OMITTED: <noscript> - case 'svg': - $this->afe->reconstruct( $this->stack ); - // We skip the spec's "adjust SVG attributes" and - // "adjust foreign attributes" steps, since the browser will - // do this later when it parses the output and it doesn't affect - // balancing. - $this->stack->insertForeignElement( - BalanceSets::SVG_NAMESPACE, $value, $attribs - ); - if ( $selfClose ) { - // emit explicit </svg> tag. - $this->stack->pop(); - } - return true; + case 'select': + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); + switch ( $this->parseMode ) { + case 'inTableMode': + case 'inCaptionMode': + case 'inTableBodyMode': + case 'inRowMode': + case 'inCellMode': + $this->switchMode( 'inSelectInTableMode' ); + return true; + default: + $this->switchMode( 'inSelectMode' ); + return true; + } - case 'caption': - case 'col': - case 'colgroup': - // OMITTED: <frame> - case 'head': - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - // Ignore table tags if we're not inTableMode - return true; - } + case 'optgroup': + case 'option': + if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { + $this->inBodyMode( 'endtag', 'option' ); + } + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - // Handle any other start tag here - $this->afe->reconstruct( $this->stack ); - $this->stack->insertHTMLElement( $value, $attribs ); - return true; - } elseif ( $token === 'endtag' ) { - switch ( $value ) { - // </body>,</html> are unsupported. - - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); - - case 'address': - case 'article': - case 'aside': - case 'blockquote': - case 'button': - case 'center': - case 'details': - case 'dialog': - case 'dir': - case 'div': - case 'dl': - case 'fieldset': - case 'figcaption': - case 'figure': - case 'footer': - case 'header': - case 'hgroup': - case 'listing': - case 'main': - case 'menu': - case 'nav': - case 'ol': - case 'pre': - case 'section': - case 'summary': - case 'ul': - // Ignore if there is not a matching open tag - if ( !$this->stack->inScope( $value ) ) { + case 'menuitem': + if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) { + $this->stack->pop(); + } + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); return true; - } - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( $value ); - return true; - case 'form': - if ( $this->stack->indexOf( 'template' ) < 0 ) { - $openform = $this->formElementPointer; - $this->formElementPointer = null; - if ( !$openform || !$this->stack->inScope( $openform ) ) { - return true; + case 'rb': + case 'rtc': + if ( $this->stack->inScope( 'ruby' ) ) { + $this->stack->generateImpliedEndTags(); } - $this->stack->generateImpliedEndTags(); - // Don't flatten yet if we're removing a <form> element - // out-of-order. (eg. `<form><div></form>`) - $flatten = ( $this->stack->currentNode === $openform ); - $this->stack->removeElement( $openform, $flatten ); - } else { - if ( !$this->stack->inScope( 'form' ) ) { - return true; + $this->stack->insertHTMLElement( $value, $attribs ); + return true; + + case 'rp': + case 'rt': + if ( $this->stack->inScope( 'ruby' ) ) { + $this->stack->generateImpliedEndTags( 'rtc' ); } - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( 'form' ); - } - return true; + $this->stack->insertHTMLElement( $value, $attribs ); + return true; - case 'p': - if ( !$this->stack->inButtonScope( 'p' ) ) { - $this->inBodyMode( 'tag', 'p', [] ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - } - $this->stack->generateImpliedEndTags( $value ); - $this->stack->popTag( $value ); - return true; + case 'math': + $this->afe->reconstruct( $this->stack ); + // We skip the spec's "adjust MathML attributes" and + // "adjust foreign attributes" steps, since the browser will + // do this later when it parses the output and it doesn't affect + // balancing. + $this->stack->insertForeignElement( + BalanceSets::MATHML_NAMESPACE, $value, $attribs + ); + if ( $selfClose ) { + // emit explicit </math> tag. + $this->stack->pop(); + } + return true; - case 'li': - if ( !$this->stack->inListItemScope( $value ) ) { - return true; // ignore - } - $this->stack->generateImpliedEndTags( $value ); - $this->stack->popTag( $value ); - return true; + case 'svg': + $this->afe->reconstruct( $this->stack ); + // We skip the spec's "adjust SVG attributes" and + // "adjust foreign attributes" steps, since the browser will + // do this later when it parses the output and it doesn't affect + // balancing. + $this->stack->insertForeignElement( + BalanceSets::SVG_NAMESPACE, $value, $attribs + ); + if ( $selfClose ) { + // emit explicit </svg> tag. + $this->stack->pop(); + } + return true; - case 'dd': - case 'dt': - if ( !$this->stack->inScope( $value ) ) { - return true; // ignore - } - $this->stack->generateImpliedEndTags( $value ); - $this->stack->popTag( $value ); - return true; + case 'caption': + case 'col': + case 'colgroup': + // OMITTED: <frame> + case 'head': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // Ignore table tags if we're not inTableMode + return true; + } - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - if ( !$this->stack->inScope( BalanceSets::$headingSet ) ) { - return true; // ignore - } - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( BalanceSets::$headingSet ); - return true; + // Handle any other start tag here + $this->afe->reconstruct( $this->stack ); + $this->stack->insertHTMLElement( $value, $attribs ); + return true; + } elseif ( $token === 'endtag' ) { + switch ( $value ) { + // </body>,</html> are unsupported. - case 'sarcasm': - // Take a deep breath, then: - break; + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + + case 'address': + case 'article': + case 'aside': + case 'blockquote': + case 'button': + case 'center': + case 'details': + case 'dialog': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'figcaption': + case 'figure': + case 'footer': + case 'header': + case 'hgroup': + case 'listing': + case 'main': + case 'menu': + case 'nav': + case 'ol': + case 'pre': + case 'section': + case 'summary': + case 'ul': + // Ignore if there is not a matching open tag + if ( !$this->stack->inScope( $value ) ) { + return true; + } + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( $value ); + return true; - case 'a': - case 'b': - case 'big': - case 'code': - case 'em': - case 'font': - case 'i': - case 'nobr': - case 's': - case 'small': - case 'strike': - case 'strong': - case 'tt': - case 'u': - if ( $this->stack->adoptionAgency( $value, $this->afe ) ) { - return true; // If we did something, we're done. - } - break; // Go to the "any other end tag" case. + case 'form': + if ( $this->stack->indexOf( 'template' ) < 0 ) { + $openform = $this->formElementPointer; + $this->formElementPointer = null; + if ( !$openform || !$this->stack->inScope( $openform ) ) { + return true; + } + $this->stack->generateImpliedEndTags(); + // Don't flatten yet if we're removing a <form> element + // out-of-order. (eg. `<form><div></form>`) + $flatten = ( $this->stack->currentNode === $openform ); + $this->stack->removeElement( $openform, $flatten ); + } else { + if ( !$this->stack->inScope( 'form' ) ) { + return true; + } + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( 'form' ); + } + return true; - case 'applet': - case 'marquee': - case 'object': - if ( !$this->stack->inScope( $value ) ) { - return true; // ignore - } - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( $value ); - $this->afe->clearToMarker(); - return true; + case 'p': + if ( !$this->stack->inButtonScope( 'p' ) ) { + $this->inBodyMode( 'tag', 'p', [] ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); + } + $this->stack->generateImpliedEndTags( $value ); + $this->stack->popTag( $value ); + return true; - case 'br': - // Turn </br> into <br> - return $this->inBodyMode( 'tag', $value, [] ); + case 'li': + if ( !$this->stack->inListItemScope( $value ) ) { + return true; // ignore + } + $this->stack->generateImpliedEndTags( $value ); + $this->stack->popTag( $value ); + return true; + + case 'dd': + case 'dt': + if ( !$this->stack->inScope( $value ) ) { + return true; // ignore + } + $this->stack->generateImpliedEndTags( $value ); + $this->stack->popTag( $value ); + return true; + + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + if ( !$this->stack->inScope( BalanceSets::$headingSet ) ) { + return true; // ignore + } + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( BalanceSets::$headingSet ); + return true; + + case 'sarcasm': + // Take a deep breath, then: + break; + + case 'a': + case 'b': + case 'big': + case 'code': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + if ( $this->stack->adoptionAgency( $value, $this->afe ) ) { + return true; // If we did something, we're done. + } + break; // Go to the "any other end tag" case. + + case 'applet': + case 'marquee': + case 'object': + if ( !$this->stack->inScope( $value ) ) { + return true; // ignore + } + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( $value ); + $this->afe->clearToMarker(); + return true; + + case 'br': + // Turn </br> into <br> + return $this->inBodyMode( 'tag', $value, [] ); } // Any other end tag goes here @@ -2987,87 +2985,87 @@ class Balancer { return true; } elseif ( $token === 'tag' ) { switch ( $value ) { - case 'caption': - $this->afe->insertMarker(); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->switchMode( 'inCaptionMode' ); - return true; - case 'colgroup': - $this->stack->clearToContext( BalanceSets::$tableContextSet ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->switchMode( 'inColumnGroupMode' ); - return true; - case 'col': - $this->inTableMode( 'tag', 'colgroup', [] ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - case 'tbody': - case 'tfoot': - case 'thead': - $this->stack->clearToContext( BalanceSets::$tableContextSet ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->switchMode( 'inTableBodyMode' ); - return true; - case 'td': - case 'th': - case 'tr': - $this->inTableMode( 'tag', 'tbody', [] ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - case 'table': - if ( !$this->stack->inTableScope( $value ) ) { - return true; // Ignore this tag. - } - $this->inTableMode( 'endtag', $value ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - - case 'style': - // OMITTED: <script> - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'caption': + $this->afe->insertMarker(); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->switchMode( 'inCaptionMode' ); + return true; + case 'colgroup': + $this->stack->clearToContext( BalanceSets::$tableContextSet ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->switchMode( 'inColumnGroupMode' ); + return true; + case 'col': + $this->inTableMode( 'tag', 'colgroup', [] ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); + case 'tbody': + case 'tfoot': + case 'thead': + $this->stack->clearToContext( BalanceSets::$tableContextSet ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->switchMode( 'inTableBodyMode' ); + return true; + case 'td': + case 'th': + case 'tr': + $this->inTableMode( 'tag', 'tbody', [] ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); + case 'table': + if ( !$this->stack->inTableScope( $value ) ) { + return true; // Ignore this tag. + } + $this->inTableMode( 'endtag', $value ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); - case 'input': - if ( !isset( $attribs['type'] ) || strcasecmp( $attribs['type'], 'hidden' ) !== 0 ) { - break; // Handle this as "everything else" - } - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - return true; + case 'style': + // OMITTED: <script> + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); - case 'form': - if ( - $this->formElementPointer || - $this->stack->indexOf( 'template' ) >= 0 - ) { - return true; // ignore this token - } - $this->formElementPointer = + case 'input': + if ( !isset( $attribs['type'] ) || strcasecmp( $attribs['type'], 'hidden' ) !== 0 ) { + break; // Handle this as "everything else" + } $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->popTag( $this->formElementPointer ); - return true; + $this->stack->pop(); + return true; + + case 'form': + if ( + $this->formElementPointer || + $this->stack->indexOf( 'template' ) >= 0 + ) { + return true; // ignore this token + } + $this->formElementPointer = + $this->stack->insertHTMLElement( $value, $attribs ); + $this->stack->popTag( $this->formElementPointer ); + return true; } // Fall through for "anything else" clause. } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'table': - if ( !$this->stack->inTableScope( $value ) ) { - return true; // Ignore. - } - $this->stack->popTag( $value ); - $this->resetInsertionMode(); - return true; - // OMITTED: <body> - case 'caption': - case 'col': - case 'colgroup': - // OMITTED: <html> - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - return true; // Ignore the token. - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'table': + if ( !$this->stack->inTableScope( $value ) ) { + return true; // Ignore. + } + $this->stack->popTag( $value ); + $this->resetInsertionMode(); + return true; + // OMITTED: <body> + case 'caption': + case 'col': + case 'colgroup': + // OMITTED: <html> + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + return true; // Ignore the token. + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } // Fall through for "anything else" clause. } elseif ( $token === 'comment' ) { @@ -3118,43 +3116,43 @@ class Balancer { private function inCaptionMode( $token, $value, $attribs = null, $selfClose = false ) { if ( $token === 'tag' ) { switch ( $value ) { - case 'caption': - case 'col': - case 'colgroup': - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - if ( $this->endCaption() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; + case 'caption': + case 'col': + case 'colgroup': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + if ( $this->endCaption() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } // Fall through to "anything else" case. } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'caption': - $this->endCaption(); - return true; - case 'table': - if ( $this->endCaption() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; - case 'body': - case 'col': - case 'colgroup': - // OMITTED: <html> - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - // Ignore the token - return true; + case 'caption': + $this->endCaption(); + return true; + case 'table': + if ( $this->endCaption() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; + case 'body': + case 'col': + case 'colgroup': + // OMITTED: <html> + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // Ignore the token + return true; } // Fall through to "anything else" case. } @@ -3174,28 +3172,28 @@ class Balancer { // Fall through to handle non-whitespace below. } elseif ( $token === 'tag' ) { switch ( $value ) { - // OMITTED: <html> - case 'col': - $this->stack->insertHTMLElement( $value, $attribs ); - $this->stack->pop(); - return true; - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + // OMITTED: <html> + case 'col': + $this->stack->insertHTMLElement( $value, $attribs ); + $this->stack->pop(); + return true; + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } // Fall through for "anything else". } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'colgroup': - if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) { + case 'colgroup': + if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) { + return true; // Ignore the token. + } + $this->stack->pop(); + $this->switchMode( 'inTableMode' ); + return true; + case 'col': return true; // Ignore the token. - } - $this->stack->pop(); - $this->switchMode( 'inTableMode' ); - return true; - case 'col': - return true; // Ignore the token. - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } // Fall through for "anything else". } elseif ( $token === 'eof' ) { @@ -3230,50 +3228,50 @@ class Balancer { private function inTableBodyMode( $token, $value, $attribs = null, $selfClose = false ) { if ( $token === 'tag' ) { switch ( $value ) { - case 'tr': - $this->stack->clearToContext( BalanceSets::$tableBodyContextSet ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->switchMode( 'inRowMode' ); - return true; - case 'th': - case 'td': - $this->inTableBodyMode( 'tag', 'tr', [] ); - $this->insertToken( $token, $value, $attribs, $selfClose ); - return true; - case 'caption': - case 'col': - case 'colgroup': - case 'tbody': - case 'tfoot': - case 'thead': - if ( $this->endSection() ) { + case 'tr': + $this->stack->clearToContext( BalanceSets::$tableBodyContextSet ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->switchMode( 'inRowMode' ); + return true; + case 'th': + case 'td': + $this->inTableBodyMode( 'tag', 'tr', [] ); $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; + return true; + case 'caption': + case 'col': + case 'colgroup': + case 'tbody': + case 'tfoot': + case 'thead': + if ( $this->endSection() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'table': - if ( $this->endSection() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; - case 'tbody': - case 'tfoot': - case 'thead': - if ( $this->stack->inTableScope( $value ) ) { - $this->endSection(); - } - return true; - // OMITTED: <body> - case 'caption': - case 'col': - case 'colgroup': - // OMITTED: <html> - case 'td': - case 'th': - case 'tr': - return true; // Ignore the token. + case 'table': + if ( $this->endSection() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; + case 'tbody': + case 'tfoot': + case 'thead': + if ( $this->stack->inTableScope( $value ) ) { + $this->endSection(); + } + return true; + // OMITTED: <body> + case 'caption': + case 'col': + case 'colgroup': + // OMITTED: <html> + case 'td': + case 'th': + case 'tr': + return true; // Ignore the token. } } // Anything else: @@ -3293,53 +3291,53 @@ class Balancer { private function inRowMode( $token, $value, $attribs = null, $selfClose = false ) { if ( $token === 'tag' ) { switch ( $value ) { - case 'th': - case 'td': - $this->stack->clearToContext( BalanceSets::$tableRowContextSet ); - $this->stack->insertHTMLElement( $value, $attribs ); - $this->switchMode( 'inCellMode' ); - $this->afe->insertMarker(); - return true; - case 'caption': - case 'col': - case 'colgroup': - case 'tbody': - case 'tfoot': - case 'thead': - case 'tr': - if ( $this->endRow() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; + case 'th': + case 'td': + $this->stack->clearToContext( BalanceSets::$tableRowContextSet ); + $this->stack->insertHTMLElement( $value, $attribs ); + $this->switchMode( 'inCellMode' ); + $this->afe->insertMarker(); + return true; + case 'caption': + case 'col': + case 'colgroup': + case 'tbody': + case 'tfoot': + case 'thead': + case 'tr': + if ( $this->endRow() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'tr': - $this->endRow(); - return true; - case 'table': - if ( $this->endRow() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; - case 'tbody': - case 'tfoot': - case 'thead': - if ( - $this->stack->inTableScope( $value ) && - $this->endRow() - ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; - // OMITTED: <body> - case 'caption': - case 'col': - case 'colgroup': - // OMITTED: <html> - case 'td': - case 'th': - return true; // Ignore the token. + case 'tr': + $this->endRow(); + return true; + case 'table': + if ( $this->endRow() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; + case 'tbody': + case 'tfoot': + case 'thead': + if ( + $this->stack->inTableScope( $value ) && + $this->endRow() + ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; + // OMITTED: <body> + case 'caption': + case 'col': + case 'colgroup': + // OMITTED: <html> + case 'td': + case 'th': + return true; // Ignore the token. } } // Anything else: @@ -3361,51 +3359,51 @@ class Balancer { private function inCellMode( $token, $value, $attribs = null, $selfClose = false ) { if ( $token === 'tag' ) { switch ( $value ) { - case 'caption': - case 'col': - case 'colgroup': - case 'tbody': - case 'td': - case 'tfoot': - case 'th': - case 'thead': - case 'tr': - if ( $this->endCell() ) { - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; + case 'caption': + case 'col': + case 'colgroup': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + if ( $this->endCell() ) { + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'td': - case 'th': - if ( $this->stack->inTableScope( $value ) ) { - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( $value ); - $this->afe->clearToMarker(); - $this->switchMode( 'inRowMode' ); - } - return true; - // OMITTED: <body> - case 'caption': - case 'col': - case 'colgroup': - // OMITTED: <html> - return true; + case 'td': + case 'th': + if ( $this->stack->inTableScope( $value ) ) { + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( $value ); + $this->afe->clearToMarker(); + $this->switchMode( 'inRowMode' ); + } + return true; + // OMITTED: <body> + case 'caption': + case 'col': + case 'colgroup': + // OMITTED: <html> + return true; - case 'table': - case 'tbody': - case 'tfoot': - case 'thead': - case 'tr': - if ( $this->stack->inTableScope( $value ) ) { - $this->stack->generateImpliedEndTags(); - $this->stack->popTag( BalanceSets::$tableCellSet ); - $this->afe->clearToMarker(); - $this->switchMode( 'inRowMode' ); - $this->insertToken( $token, $value, $attribs, $selfClose ); - } - return true; + case 'table': + case 'tbody': + case 'tfoot': + case 'thead': + case 'tr': + if ( $this->stack->inTableScope( $value ) ) { + $this->stack->generateImpliedEndTags(); + $this->stack->popTag( BalanceSets::$tableCellSet ); + $this->afe->clearToMarker(); + $this->switchMode( 'inRowMode' ); + $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } } // Anything else: @@ -3420,65 +3418,65 @@ class Balancer { return $this->inBodyMode( $token, $value, $attribs, $selfClose ); } elseif ( $token === 'tag' ) { switch ( $value ) { - // OMITTED: <html> - case 'option': - if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { - $this->stack->pop(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; - case 'optgroup': - if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { - $this->stack->pop(); - } - if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) { - $this->stack->pop(); - } - $this->stack->insertHTMLElement( $value, $attribs ); - return true; - case 'select': - $this->inSelectMode( 'endtag', $value ); // treat it like endtag - return true; - case 'input': - case 'keygen': - case 'textarea': - if ( !$this->stack->inSelectScope( 'select' ) ) { - return true; // ignore token (fragment case) - } - $this->inSelectMode( 'endtag', 'select' ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - case 'script': - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + // OMITTED: <html> + case 'option': + if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { + $this->stack->pop(); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; + case 'optgroup': + if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { + $this->stack->pop(); + } + if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) { + $this->stack->pop(); + } + $this->stack->insertHTMLElement( $value, $attribs ); + return true; + case 'select': + $this->inSelectMode( 'endtag', $value ); // treat it like endtag + return true; + case 'input': + case 'keygen': + case 'textarea': + if ( !$this->stack->inSelectScope( 'select' ) ) { + return true; // ignore token (fragment case) + } + $this->inSelectMode( 'endtag', 'select' ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); + case 'script': + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'optgroup': - if ( - $this->stack->currentNode->isHtmlNamed( 'option' ) && - $this->stack->length() >= 2 && - $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed( 'optgroup' ) - ) { - $this->stack->pop(); - } - if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) { - $this->stack->pop(); - } - return true; - case 'option': - if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { - $this->stack->pop(); - } - return true; - case 'select': - if ( !$this->stack->inSelectScope( $value ) ) { - return true; // fragment case - } - $this->stack->popTag( $value ); - $this->resetInsertionMode(); - return true; - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'optgroup': + if ( + $this->stack->currentNode->isHtmlNamed( 'option' ) && + $this->stack->length() >= 2 && + $this->stack->node( $this->stack->length() - 2 )->isHtmlNamed( 'optgroup' ) + ) { + $this->stack->pop(); + } + if ( $this->stack->currentNode->isHtmlNamed( 'optgroup' ) ) { + $this->stack->pop(); + } + return true; + case 'option': + if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) { + $this->stack->pop(); + } + return true; + case 'select': + if ( !$this->stack->inSelectScope( $value ) ) { + return true; // fragment case + } + $this->stack->popTag( $value ); + $this->resetInsertionMode(); + return true; + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } } elseif ( $token === 'comment' ) { $this->stack->insertComment( $value ); @@ -3490,24 +3488,24 @@ class Balancer { private function inSelectInTableMode( $token, $value, $attribs = null, $selfClose = false ) { switch ( $value ) { - case 'caption': - case 'table': - case 'tbody': - case 'tfoot': - case 'thead': - case 'tr': - case 'td': - case 'th': - if ( $token === 'tag' ) { - $this->inSelectInTableMode( 'endtag', 'select' ); - return $this->insertToken( $token, $value, $attribs, $selfClose ); - } elseif ( $token === 'endtag' ) { - if ( $this->stack->inTableScope( $value ) ) { + case 'caption': + case 'table': + case 'tbody': + case 'tfoot': + case 'thead': + case 'tr': + case 'td': + case 'th': + if ( $token === 'tag' ) { $this->inSelectInTableMode( 'endtag', 'select' ); return $this->insertToken( $token, $value, $attribs, $selfClose ); + } elseif ( $token === 'endtag' ) { + if ( $this->stack->inTableScope( $value ) ) { + $this->inSelectInTableMode( 'endtag', 'select' ); + return $this->insertToken( $token, $value, $attribs, $selfClose ); + } + return true; } - return true; - } } // anything else return $this->inSelectMode( $token, $value, $attribs, $selfClose ); @@ -3529,50 +3527,50 @@ class Balancer { return true; } elseif ( $token === 'tag' ) { switch ( $value ) { - case 'base': - case 'basefont': - case 'bgsound': - case 'link': - case 'meta': - case 'noframes': - // OMITTED: <script> - case 'style': - case 'template': - // OMITTED: <title> - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'base': + case 'basefont': + case 'bgsound': + case 'link': + case 'meta': + case 'noframes': + // OMITTED: <script> + case 'style': + case 'template': + // OMITTED: <title> + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); - case 'caption': - case 'colgroup': - case 'tbody': - case 'tfoot': - case 'thead': - return $this->switchModeAndReprocess( - 'inTableMode', $token, $value, $attribs, $selfClose - ); + case 'caption': + case 'colgroup': + case 'tbody': + case 'tfoot': + case 'thead': + return $this->switchModeAndReprocess( + 'inTableMode', $token, $value, $attribs, $selfClose + ); - case 'col': - return $this->switchModeAndReprocess( - 'inColumnGroupMode', $token, $value, $attribs, $selfClose - ); + case 'col': + return $this->switchModeAndReprocess( + 'inColumnGroupMode', $token, $value, $attribs, $selfClose + ); - case 'tr': - return $this->switchModeAndReprocess( - 'inTableBodyMode', $token, $value, $attribs, $selfClose - ); + case 'tr': + return $this->switchModeAndReprocess( + 'inTableBodyMode', $token, $value, $attribs, $selfClose + ); - case 'td': - case 'th': - return $this->switchModeAndReprocess( - 'inRowMode', $token, $value, $attribs, $selfClose - ); + case 'td': + case 'th': + return $this->switchModeAndReprocess( + 'inRowMode', $token, $value, $attribs, $selfClose + ); } return $this->switchModeAndReprocess( 'inBodyMode', $token, $value, $attribs, $selfClose ); } elseif ( $token === 'endtag' ) { switch ( $value ) { - case 'template': - return $this->inHeadMode( $token, $value, $attribs, $selfClose ); + case 'template': + return $this->inHeadMode( $token, $value, $attribs, $selfClose ); } return true; } else {