Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.06% covered (success)
97.06%
66 / 68
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AfterHead
97.06% covered (success)
97.06%
66 / 68
75.00% covered (warning)
75.00%
3 / 4
26
0.00% covered (danger)
0.00%
0 / 1
 characters
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
 startTag
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
16
 endTag
85.71% covered (warning)
85.71%
12 / 14
0.00% covered (danger)
0.00%
0 / 1
6.10
 endDocument
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Wikimedia\RemexHtml\TreeBuilder;
4
5use Wikimedia\RemexHtml\Tokenizer\Attributes;
6use Wikimedia\RemexHtml\Tokenizer\PlainAttributes;
7
8/**
9 * The "after head" insertion mode
10 */
11class AfterHead extends InsertionMode {
12    public function characters( $text, $start, $length, $sourceStart, $sourceLength ) {
13        $builder = $this->builder;
14        $dispatcher = $this->dispatcher;
15
16        // Insert whitespace
17        [ $part1, $part2 ] = $this->splitInitialMatch(
18            true, "\t\n\f\r ", $text, $start, $length, $sourceStart, $sourceLength );
19        [ $start, $length, $sourceStart, $sourceLength ] = $part1;
20        if ( $length ) {
21            $builder->insertCharacters( $text, $start, $length,
22                $sourceStart, $sourceLength );
23        }
24
25        // Switch mode on non-whitespace
26        [ $start, $length, $sourceStart, $sourceLength ] = $part2;
27        if ( $length ) {
28            $builder->insertElement( 'body', new PlainAttributes, false, $sourceStart, 0 );
29            $dispatcher->switchMode( Dispatcher::IN_BODY )
30                ->characters( $text, $start, $length, $sourceStart, $sourceLength );
31        }
32    }
33
34    public function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) {
35        $builder = $this->builder;
36        $stack = $builder->stack;
37        $dispatcher = $this->dispatcher;
38
39        switch ( $name ) {
40            case 'html':
41                $dispatcher->inBody->startTag( $name, $attrs, $selfClose,
42                    $sourceStart, $sourceLength );
43                break;
44
45            case 'body':
46                $builder->insertElement( $name, $attrs, false, $sourceStart, $sourceLength );
47                $builder->framesetOK = false;
48                $dispatcher->switchMode( Dispatcher::IN_BODY );
49                break;
50
51            case 'frameset':
52                $builder->insertElement( $name, $attrs, false, $sourceStart, $sourceLength );
53                $dispatcher->switchMode( Dispatcher::IN_FRAMESET );
54                break;
55
56            case 'base':
57            case 'basefont':
58            case 'bgsound':
59            case 'link':
60            case 'meta':
61            case 'noframes':
62            case 'script':
63            case 'style':
64            case 'template':
65            case 'title':
66                $builder->error( "unexpected <$name> after </head>, accepting", $sourceStart );
67                $stack->push( $builder->headElement );
68                $dispatcher->inHead->startTag(
69                    $name, $attrs, $selfClose, $sourceStart, $sourceLength );
70                $stack->remove( $builder->headElement );
71                break;
72
73            case 'head':
74                $builder->error( "unexpected <head> after </head>, ignoring", $sourceStart );
75                return;
76
77            default:
78                $builder->insertElement( 'body', new PlainAttributes, false, $sourceStart, 0 );
79                $dispatcher->switchMode( Dispatcher::IN_BODY )
80                    ->startTag( $name, $attrs, $selfClose, $sourceStart, $sourceLength );
81        }
82    }
83
84    public function endTag( $name, $sourceStart, $sourceLength ) {
85        $builder = $this->builder;
86        $dispatcher = $this->dispatcher;
87
88        switch ( $name ) {
89            case 'template':
90                $dispatcher->inHead->endTag( $name, $sourceStart, $sourceLength );
91                break;
92
93            case 'body':
94            case 'html':
95            case 'br':
96                $builder->insertElement( 'body', new PlainAttributes, false, $sourceStart, 0 );
97                $dispatcher->switchMode( Dispatcher::IN_BODY )
98                    ->endTag( $name, $sourceStart, $sourceLength );
99                break;
100
101            default:
102                $builder->error( "unexpected </$name> after head, ignoring", $sourceStart );
103                return;
104        }
105    }
106
107    public function endDocument( $pos ) {
108        $this->builder->insertElement( 'body', new PlainAttributes, false, $pos, 0 );
109        $this->dispatcher->switchMode( Dispatcher::IN_BODY )
110            ->endDocument( $pos );
111    }
112}