X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/InTable.php diff --git a/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/InTable.php b/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/InTable.php new file mode 100644 index 00000000..5827c7f4 --- /dev/null +++ b/vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/InTable.php @@ -0,0 +1,181 @@ + true, + 'template' => true, + 'html' => true + ]; + + public function characters( $text, $start, $length, $sourceStart, $sourceLength ) { + $allowed = [ + 'table' => true, + 'tbody' => true, + 'tfoot' => true, + 'thead' => true, + 'tr' => true ]; + if ( isset( $allowed[$this->builder->stack->current->htmlName] ) ) { + $this->builder->pendingTableCharacters = []; + $this->dispatcher->switchAndSave( Dispatcher::IN_TABLE_TEXT ) + ->characters( $text, $start, $length, $sourceStart, $sourceLength ); + } else { + $this->builder->error( 'unexpected text in table, fostering', $sourceStart ); + $this->builder->fosterParenting = true; + $this->dispatcher->inBody->characters( + $text, $start, $length, $sourceStart, $sourceLength ); + $this->builder->fosterParenting = false; + } + } + + public function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) { + $builder = $this->builder; + $dispatcher = $this->dispatcher; + $stack = $builder->stack; + + switch ( $name ) { + case 'caption': + $builder->clearStackBack( self::$tableContext, $sourceStart ); + $builder->afe->insertMarker(); + $dispatcher->switchMode( Dispatcher::IN_CAPTION ); + $builder->insertElement( $name, $attrs, false, + $sourceStart, $sourceLength ); + break; + + case 'colgroup': + $builder->clearStackBack( self::$tableContext, $sourceStart ); + $dispatcher->switchMode( Dispatcher::IN_COLUMN_GROUP ); + $builder->insertElement( $name, $attrs, false, + $sourceStart, $sourceLength ); + break; + + case 'col': + $builder->clearStackBack( self::$tableContext, $sourceStart ); + $builder->insertElement( 'colgroup', new PlainAttributes, false, + $sourceStart, 0 ); + $dispatcher->switchMode( Dispatcher::IN_COLUMN_GROUP ) + ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); + break; + + case 'tbody': + case 'tfoot': + case 'thead': + $builder->clearStackBack( self::$tableContext, $sourceStart ); + $builder->insertElement( $name, $attrs, false, + $sourceStart, $sourceLength ); + $dispatcher->switchMode( Dispatcher::IN_TABLE_BODY ); + break; + + case 'td': + case 'th': + case 'tr': + $builder->clearStackBack( self::$tableContext, $sourceStart ); + $builder->insertElement( 'tbody', new PlainAttributes, false, + $sourceStart, $sourceLength ); + $dispatcher->switchMode( Dispatcher::IN_TABLE_BODY ) + ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); + break; + + case 'table': + $builder->error( 'unexpected in table', $sourceStart ); + if ( !$stack->isInTableScope( 'table' ) ) { + // Ignore + break; + } + $builder->popAllUpToName( 'table', $sourceStart, 0 ); + $dispatcher->reset() + ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); + break; + + case 'style': + case 'script': + case 'template': + $dispatcher->inHead->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); + break; + + case 'form': + if ( $stack->hasTemplate() || $builder->formElement !== null ) { + $builder->error( 'invalid form in table, ignoring', $sourceStart ); + // Ignore + break; + } + $builder->error( 'invalid form in table, inserting void element', $sourceStart ); + $elt = $builder->insertElement( 'form', $attrs, true, + $sourceStart, $sourceLength ); + $builder->formElement = $elt; + break; + + case 'input': + if ( isset( $attrs['type'] ) && strcasecmp( $attrs['type'], 'hidden' ) === 0 ) { + $builder->error( 'begrudgingly accepting a hidden input in table mode', + $sourceStart ); + $dispatcher->ack = true; + $builder->insertElement( $name, $attrs, true, $sourceStart, $sourceLength ); + break; + } + // Fall through + + default: + $builder->error( 'invalid start tag in table, fostering', $sourceStart ); + $builder->fosterParenting = true; + $dispatcher->inBody->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); + $builder->fosterParenting = false; + break; + } + } + + public function endTag( $name, $sourceStart, $sourceLength ) { + $builder = $this->builder; + $stack = $builder->stack; + $dispatcher = $this->dispatcher; + + switch ( $name ) { + case 'table': + if ( !$stack->isInTableScope( 'table' ) ) { + $builder->error( '
found but no table element in scope, ignoring', $sourceStart ); + // Ignore + break; + } + $builder->popAllUpToName( 'table', $sourceStart, $sourceLength ); + $dispatcher->reset(); + break; + + case 'body': + case 'caption': + case 'col': + case 'colgroup': + case 'html': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + $builder->error( 'ignoring invalid end tag inside table', $sourceStart ); + break; + + case 'template': + $dispatcher->inHead->endTag( $name, $sourceStart, $sourceLength ); + break; + + default: + $builder->error( 'unexpected end tag in table, fostering', $sourceStart ); + $builder->fosterParenting = true; + $dispatcher->inBody->endTag( $name, $sourceStart, $sourceLength ); + $builder->fosterParenting = false; + } + } + + public function endDocument( $pos ) { + $this->dispatcher->inBody->endDocument( $pos ); + } +}