1<?php 2 3namespace RemexHtml\TreeBuilder; 4 5use RemexHtml\Tokenizer\Attributes; 6 7/** 8 * The "in caption" insertion mode 9 */ 10class 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} 106