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