]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/InTableBody.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / vendor / wikimedia / remex-html / RemexHtml / TreeBuilder / InTableBody.php
1 <?php
2
3 namespace RemexHtml\TreeBuilder;
4 use RemexHtml\Tokenizer\Attributes;
5 use RemexHtml\Tokenizer\PlainAttributes;
6
7 /**
8  * The "in table body" insertion mode
9  */
10 class InTableBody extends InsertionMode {
11         private static $tableBodyContext = [
12                 'tbody' => true,
13                 'tfoot' => true,
14                 'thead' => true,
15                 'template' => true,
16                 'html' => true
17         ];
18
19         public function characters( $text, $start, $length, $sourceStart, $sourceLength ) {
20                 $this->dispatcher->inTable->characters( $text, $start, $length,
21                         $sourceStart, $sourceLength );
22         }
23
24         public function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) {
25                 $builder = $this->builder;
26                 $stack = $builder->stack;
27                 $dispatcher = $this->dispatcher;
28
29                 switch ( $name ) {
30                 case 'tr':
31                         $builder->clearStackBack( self::$tableBodyContext, $sourceStart );
32                         $builder->insertElement( $name, $attrs, false, $sourceStart, $sourceLength );
33                         $dispatcher->switchMode( Dispatcher::IN_ROW );
34                         break;
35
36                 case 'th':
37                 case 'td':
38                         $builder->error( "<$name> encountered in table body (not row) mode", $sourceStart );
39                         $builder->clearStackBack( self::$tableBodyContext, $sourceStart );
40                         $builder->insertElement( 'tr', new PlainAttributes, false, $sourceStart, 0 );
41                         $dispatcher->switchMode( Dispatcher::IN_ROW )
42                                 ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength );
43                         break;
44
45                 case 'caption':
46                 case 'col':
47                 case 'colgroup':
48                 case 'tbody':
49                 case 'tfoot':
50                 case 'thead':
51                         if ( !$stack->isInTableScope( 'tbody' )
52                           && !$stack->isInTableScope( 'thead' )
53                           && !$stack->isInTableScope( 'tfoot' )
54                         ) {
55                                 $builder->error( "<$name> encountered in table body mode " .
56                                         "when there is no tbody/thead/tfoot in scope", $sourceStart );
57                                 return;
58                         }
59                         $builder->clearStackBack( self::$tableBodyContext, $sourceStart );
60                         $builder->pop( $sourceStart, 0 );
61                         $dispatcher->switchMode( Dispatcher::IN_TABLE )
62                                 ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength );
63                         break;
64
65                 default:
66                         $dispatcher->inTable->startTag( $name, $attrs, $selfClose,
67                                 $sourceStart, $sourceLength );
68                 }
69         }
70
71         public function endTag( $name, $sourceStart, $sourceLength ) {
72                 $builder = $this->builder;
73                 $stack = $builder->stack;
74                 $dispatcher = $this->dispatcher;
75
76                 switch ( $name ) {
77                 case 'tbody':
78                 case 'tfoot':
79                 case 'thead':
80                         if ( !$stack->isInTableScope( $name ) ) {
81                                 $builder->error( "</$name> found but no $name in scope", $sourceStart );
82                                 return;
83                         }
84                         $builder->clearStackBack( self::$tableBodyContext, $sourceStart );
85                         $builder->pop( $sourceStart, $sourceLength );
86                         $dispatcher->switchMode( Dispatcher::IN_TABLE );
87                         break;
88
89                 case 'body':
90                 case 'caption':
91                 case 'col':
92                 case 'colgroup':
93                 case 'html':
94                 case 'td':
95                 case 'th':
96                 case 'tr':
97                         $builder->error( "</$name> found in table body mode, ignoring", $sourceStart );
98                         return;
99
100                 default:
101                         $dispatcher->inTable->endTag( $name, $sourceStart, $sourceLength );
102                 }
103         }
104
105         public function endDocument( $pos ) {
106                 $this->dispatcher->inTable->endDocument( $pos );
107         }
108 }