Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
65 / 65 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
1 / 1 |
InCaption | |
100.00% |
65 / 65 |
|
100.00% |
4 / 4 |
32 | |
100.00% |
1 / 1 |
characters | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
startTag | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
12 | |||
endTag | |
100.00% |
41 / 41 |
|
100.00% |
1 / 1 |
18 | |||
endDocument | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace Wikimedia\RemexHtml\TreeBuilder; |
4 | |
5 | use Wikimedia\RemexHtml\Tokenizer\Attributes; |
6 | |
7 | /** |
8 | * The "in caption" insertion mode |
9 | */ |
10 | class InCaption extends InsertionMode { |
11 | public function characters( $text, $start, $length, $sourceStart, $sourceLength ) { |
12 | $this->dispatcher->inBody->characters( $text, $start, $length, |
13 | $sourceStart, $sourceLength ); |
14 | } |
15 | |
16 | public function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) { |
17 | $builder = $this->builder; |
18 | $stack = $builder->stack; |
19 | switch ( $name ) { |
20 | case 'caption': |
21 | case 'col': |
22 | case 'colgroup': |
23 | case 'tbody': |
24 | case 'td': |
25 | case 'tfoot': |
26 | case 'th': |
27 | case 'thead': |
28 | case 'tr': |
29 | $builder->error( "start tag <$name> not allowed in caption", $sourceStart ); |
30 | if ( !$stack->isInTableScope( 'caption' ) ) { |
31 | // Ignore |
32 | return; |
33 | } |
34 | $builder->popAllUpToName( 'caption', $sourceStart, 0 ); |
35 | $builder->afe->clearToMarker(); |
36 | $this->dispatcher->switchMode( Dispatcher::IN_TABLE ) |
37 | ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength ); |
38 | break; |
39 | |
40 | default: |
41 | $this->dispatcher->inBody->startTag( $name, $attrs, $selfClose, |
42 | $sourceStart, $sourceLength ); |
43 | } |
44 | } |
45 | |
46 | public function endTag( $name, $sourceStart, $sourceLength ) { |
47 | $dispatcher = $this->dispatcher; |
48 | $builder = $this->builder; |
49 | $stack = $builder->stack; |
50 | |
51 | switch ( $name ) { |
52 | case 'caption': |
53 | if ( !$stack->isInTableScope( 'caption' ) ) { |
54 | $builder->error( "</caption> matches a start tag which is not in scope, ignoring", |
55 | $sourceStart ); |
56 | return; |
57 | } |
58 | |
59 | $builder->generateImpliedEndTags( false, $sourceStart ); |
60 | if ( $stack->current->htmlName !== 'caption' ) { |
61 | $builder->error( "</caption> found but another element is open", $sourceStart ); |
62 | } |
63 | $builder->popAllUpToName( 'caption', $sourceStart, $sourceLength ); |
64 | $builder->afe->clearToMarker(); |
65 | $dispatcher->switchMode( Dispatcher::IN_TABLE ); |
66 | break; |
67 | |
68 | case 'table': |
69 | if ( !$stack->isInTableScope( 'caption' ) ) { |
70 | $builder->error( '</table> found in caption, but there is no ' . |
71 | 'caption in scope, ignoring', $sourceStart ); |
72 | return; |
73 | } |
74 | $builder->generateImpliedEndTags( false, $sourceStart ); |
75 | if ( $stack->current->htmlName !== 'caption' ) { |
76 | $builder->error( '</table> found in caption, closing caption', $sourceStart ); |
77 | } |
78 | $builder->popAllUpToName( 'caption', $sourceStart, 0 ); |
79 | $builder->afe->clearToMarker(); |
80 | $dispatcher->switchMode( Dispatcher::IN_TABLE ) |
81 | ->endTag( $name, $sourceStart, $sourceLength ); |
82 | break; |
83 | |
84 | case 'body': |
85 | case 'col': |
86 | case 'colgroup': |
87 | case 'html': |
88 | case 'tbody': |
89 | case 'td': |
90 | case 'tfoot': |
91 | case 'th': |
92 | case 'thead': |
93 | case 'tr': |
94 | $this->builder->error( "end tag </$name> ignored in caption mode", $sourceStart ); |
95 | break; |
96 | |
97 | default: |
98 | $this->dispatcher->inBody->endTag( $name, $sourceStart, $sourceLength ); |
99 | } |
100 | } |
101 | |
102 | public function endDocument( $pos ) { |
103 | $this->dispatcher->inBody->endDocument( $pos ); |
104 | } |
105 | } |