]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/wikimedia/remex-html/RemexHtml/TreeBuilder/TreeMutationTracer.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / wikimedia / remex-html / RemexHtml / TreeBuilder / TreeMutationTracer.php
1 <?php
2
3 namespace RemexHtml\TreeBuilder;
4 use RemexHtml\Tokenizer\Attributes;
5
6 /**
7  * This is a debugging helper class which calls the supplied callback function
8  * each time there is a TreeHandler event, giving a descriptive message. It
9  * then forwards the event through to the supplied handler.
10  */
11 class TreeMutationTracer implements TreeHandler {
12
13         /**
14          * Constructor.
15          *
16          * @param TreeHandler $handler The next pipeline stage
17          * @param callable $callback The message output function
18          * @param integer $verbosity Set to non-zero to call dump() on the handler
19          *   before and after each event.
20          */
21         public function __construct( TreeHandler $handler, callable $callback, $verbosity = 0 ) {
22                 $this->handler = $handler;
23                 $this->callback = $callback;
24                 $this->verbosity = $verbosity;
25         }
26
27         /**
28          * Send a message
29          */
30         private function trace( $msg ) {
31                 call_user_func( $this->callback, "[Tree] $msg" );
32         }
33
34         /**
35          * Get a debug tag for an element or null
36          *
37          * @param Element|null $element
38          */
39         private function getDebugTag( $element ) {
40                 return $element ? $element->getDebugTag() : '';
41         }
42
43         /**
44          * Get a short excerpt of some text
45          *
46          * @param string $text
47          * @return string
48          */
49         private function excerpt( $text ) {
50                 if ( strlen( $text ) > 20 ) {
51                         $text = substr( $text, 0, 20 ) . '...';
52                 }
53                 return str_replace( "\n", "\\n", $text );
54         }
55
56         /**
57          * Get a readable version of the TreeBuilder preposition constants
58          */
59         private function getPrepositionName( $prep ) {
60                 $names = [
61                         TreeBuilder::BEFORE => 'before',
62                         TreeBuilder::UNDER => 'under',
63                         TreeBuilder::ROOT => 'under root'
64                 ];
65                 return isset( $names[$prep] ) ? $names[$prep] : '???';
66         }
67
68         /**
69          * A helper called before the underlying handler is called.
70          */
71         private function before() {
72                 if ( $this->verbosity > 0 ) {
73                         $this->trace( "Before: " . $this->handler->dump() . "\n" );
74                 }
75         }
76
77         /**
78          * A helper called after the underlying handler is called.
79          */
80         private function after() {
81                 if ( $this->verbosity > 0 ) {
82                         $this->trace( "After:  " . $this->handler->dump() . "\n" );
83                 }
84         }
85
86         public function startDocument( $fns, $fn ) {
87                 $this->trace( "startDocument" );
88                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
89         }
90
91         public function endDocument( $pos ) {
92                 $this->trace( "endDocument $pos" );
93                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
94         }
95
96         public function characters( $preposition, $refNode, $text, $start, $length,
97                 $sourceStart, $sourceLength
98         ) {
99                 $excerpt = $this->excerpt( substr( $text, $start, $length ) );
100                 $prepName = $this->getPrepositionName( $preposition );
101                 $refTag = $this->getDebugTag( $refNode );
102
103                 $this->trace( "characters \"$excerpt\", $prepName $refTag, start=$sourceStart" );
104                 $this->before();
105                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
106                 $this->after();
107         }
108
109         public function insertElement( $preposition, $refNode, Element $element, $void,
110                 $sourceStart, $sourceLength
111         ) {
112                 $prepName = $this->getPrepositionName( $preposition );
113                 $refTag = $this->getDebugTag( $refNode );
114                 $elementTag = $this->getDebugTag( $element );
115                 $voidMsg = $void ? 'void' : '';
116                 $this->trace( "insert $elementTag $voidMsg, $prepName $refTag, start=$sourceStart" );
117                 $this->before();
118                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
119                 $this->after();
120         }
121
122         public function endTag( Element $element, $sourceStart, $sourceLength ) {
123                 $elementTag = $this->getDebugTag( $element );
124                 $this->trace( "end $elementTag, start=$sourceStart" );
125                 $this->before();
126                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
127                 $this->after();
128         }
129
130         public function doctype( $name, $public, $system, $quirks, $sourceStart, $sourceLength ) {
131                 $quirksTypes = [
132                         TreeBuilder::QUIRKS => 'quirks',
133                         TreeBuilder::NO_QUIRKS => 'no-quirks',
134                         TreeBuilder::LIMITED_QUIRKS => 'limited-quirks'
135                 ];
136                 $quirksMsg = $quirksTypes[$quirks];
137                 $this->trace( "doctype $name, public=\"$public\", system=\"$system\", " .
138                         "$quirksMsg, start=$sourceStart" );
139                 $this->before();
140                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
141                 $this->after();
142         }
143
144         public function comment( $preposition, $refNode, $text, $sourceStart, $sourceLength ) {
145                 $prepName = $this->getPrepositionName( $preposition );
146                 $refTag = $this->getDebugTag( $refNode );
147                 $excerpt = $this->excerpt( $text );
148
149                 $this->trace( "comment \"$excerpt\", $prepName $refTag, start=$sourceStart" );
150                 $this->before();
151                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
152                 $this->after();
153         }
154
155         public function error( $text, $pos ) {
156                 $this->trace( "error \"$text\", start=$pos" );
157                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
158         }
159
160         public function mergeAttributes( Element $element, Attributes $attrs, $sourceStart ) {
161                 $elementTag = $this->getDebugTag( $element );
162                 $this->trace( "merge $elementTag, start=$sourceStart" );
163                 $this->before();
164                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
165         }
166
167         public function removeNode( Element $element, $sourceStart ) {
168                 $elementTag = $this->getDebugTag( $element );
169                 $this->trace( "remove $elementTag, start=$sourceStart" );
170                 $this->before();
171                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
172                 $this->after();
173         }
174
175         public function reparentChildren( Element $element, Element $newParent, $sourceStart ) {
176                 $elementTag = $this->getDebugTag( $element );
177                 $newParentTag = $this->getDebugTag( $newParent );
178                 $this->trace( "reparent children of $elementTag under $newParentTag, start=$sourceStart" );
179                 $this->before();
180                 call_user_func_array( [ $this->handler, __FUNCTION__ ], func_get_args() );
181                 $this->after();
182         }
183 }