Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
97.37% |
37 / 38 |
|
92.31% |
12 / 13 |
CRAP | |
0.00% |
0 / 1 |
DispatchTracer | |
97.37% |
37 / 38 |
|
92.31% |
12 / 13 |
20 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
trace | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
excerpt | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
2.15 | |||
wrap | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
getHandlerName | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
startDocument | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
endDocument | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
error | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
characters | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
startTag | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
endTag | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
doctype | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
comment | |
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 | use Wikimedia\RemexHtml\Tokenizer\TokenHandler; |
7 | use Wikimedia\RemexHtml\Tokenizer\Tokenizer; |
8 | |
9 | /** |
10 | * This is a debugging helper class which calls a callback function with a |
11 | * descriptive message each time a token event comes from the Tokenizer. The |
12 | * messages include information about the current state and transitions of the |
13 | * Dispatcher which is the next stage in the pipeline. |
14 | */ |
15 | class DispatchTracer implements TokenHandler { |
16 | private $input; |
17 | private $dispatcher; |
18 | private $callback; |
19 | |
20 | public function __construct( $input, Dispatcher $dispatcher, callable $callback ) { |
21 | $this->input = $input; |
22 | $this->dispatcher = $dispatcher; |
23 | $this->callback = $callback; |
24 | } |
25 | |
26 | private function trace( $msg ) { |
27 | call_user_func( $this->callback, "[Dispatch] $msg" ); |
28 | } |
29 | |
30 | private function excerpt( $text ) { |
31 | if ( strlen( $text ) > 20 ) { |
32 | $text = substr( $text, 0, 20 ) . '...'; |
33 | } |
34 | return str_replace( "\n", "\\n", $text ); |
35 | } |
36 | |
37 | private function wrap( $funcName, $sourceStart, $sourceLength, $args ) { |
38 | $prevHandler = $this->getHandlerName(); |
39 | $excerpt = $this->excerpt( substr( $this->input, $sourceStart, $sourceLength ) ); |
40 | $msg = "$funcName $prevHandler \"$excerpt\""; |
41 | $this->trace( $msg ); |
42 | call_user_func_array( [ $this->dispatcher, $funcName ], $args ); |
43 | $handler = $this->getHandlerName(); |
44 | if ( $prevHandler !== $handler ) { |
45 | $this->trace( "$prevHandler -> $handler" ); |
46 | } |
47 | } |
48 | |
49 | private function getHandlerName() { |
50 | $handler = $this->dispatcher->getHandler(); |
51 | $name = $handler ? get_class( $handler ) : 'NULL'; |
52 | $slashPos = strrpos( $name, '\\' ); |
53 | if ( $slashPos === false ) { |
54 | return $name; |
55 | } else { |
56 | return substr( $name, $slashPos + 1 ); |
57 | } |
58 | } |
59 | |
60 | public function startDocument( Tokenizer $tokenizer, $ns, $name ) { |
61 | $prevHandler = $this->getHandlerName(); |
62 | $nsMsg = $ns === null ? 'NULL' : $ns; |
63 | $nameMsg = $name === null ? 'NULL' : $name; |
64 | $this->trace( "startDocument $prevHandler $nsMsg $nameMsg" ); |
65 | $this->dispatcher->startDocument( $tokenizer, $ns, $name ); |
66 | $handler = $this->getHandlerName(); |
67 | if ( $prevHandler !== $handler ) { |
68 | $this->trace( "$prevHandler -> $handler" ); |
69 | } |
70 | } |
71 | |
72 | public function endDocument( $pos ) { |
73 | $this->wrap( __FUNCTION__, $pos, 0, func_get_args() ); |
74 | } |
75 | |
76 | public function error( $text, $pos ) { |
77 | $handler = $this->getHandlerName(); |
78 | $this->trace( "error $handler \"$text\"" ); |
79 | $this->dispatcher->error( $text, $pos ); |
80 | } |
81 | |
82 | public function characters( $text, $start, $length, $sourceStart, $sourceLength ) { |
83 | $this->wrap( __FUNCTION__, $sourceStart, $sourceLength, func_get_args() ); |
84 | } |
85 | |
86 | public function startTag( $name, Attributes $attrs, $selfClose, $sourceStart, $sourceLength ) { |
87 | $this->wrap( __FUNCTION__, $sourceStart, $sourceLength, func_get_args() ); |
88 | } |
89 | |
90 | public function endTag( $name, $sourceStart, $sourceLength ) { |
91 | $this->wrap( __FUNCTION__, $sourceStart, $sourceLength, func_get_args() ); |
92 | } |
93 | |
94 | public function doctype( $name, $public, $system, $quirks, $sourceStart, $sourceLength ) { |
95 | $this->wrap( __FUNCTION__, $sourceStart, $sourceLength, func_get_args() ); |
96 | } |
97 | |
98 | public function comment( $text, $sourceStart, $sourceLength ) { |
99 | $this->wrap( __FUNCTION__, $sourceStart, $sourceLength, func_get_args() ); |
100 | } |
101 | } |