]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - vendor/wikimedia/remex-html/RemexHtml/Serializer/TestFormatter.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / vendor / wikimedia / remex-html / RemexHtml / Serializer / TestFormatter.php
1 <?php
2
3 namespace RemexHtml\Serializer;
4 use RemexHtml\Tokenizer\Attribute;
5 use RemexHtml\Tokenizer\Attributes;
6 use RemexHtml\Tokenizer\PlainAttributes;
7 use RemexHtml\HTMLData;
8 use RemexHtml\DOM\DOMFormatter;
9 use RemexHtml\DOM\DOMUtils;
10
11 /**
12  * A Formatter which is used to format documents in (almost) the way they
13  * appear in the html5lib tests. A little bit of post-processing is required
14  * in the PHPUnit tests.
15  */
16 class TestFormatter implements Formatter, DOMFormatter {
17         private static $attrNamespaces = [
18                 HTMLData::NS_XML => 'xml',
19                 HTMLData::NS_XLINK => 'xlink',
20                 HTMLData::NS_XMLNS => 'xmlns',
21         ];
22
23         public function startDocument( $fragmentNamespace, $fragmentName ) {
24                 return '';
25         }
26
27         public function doctype( $name, $public, $system ) {
28                 $ret = "<!DOCTYPE $name";
29                 if ( $public !== '' || $system !== '' ) {
30                         $ret .= " \"$public\" \"$system\"";
31                 }
32                 $ret .= ">\n";
33                 return $ret;
34         }
35
36         public function characters( SerializerNode $parent, $text, $start, $length ) {
37                 return $this->formatCharacters( substr( $text, $start, $length ) );
38         }
39
40         private function formatCharacters( $text ) {
41                 return '"' .
42                         str_replace( "\n", "<EOL>", $text ) .
43                         "\"\n";
44         }
45
46         public function element( SerializerNode $parent, SerializerNode $node, $contents ) {
47                 return $this->formatElement( $node->namespace, $node->name,
48                         $node->attrs->getObjects(), $contents );
49         }
50
51         private function formatElement( $namespace, $name, $attrs, $contents ) {
52                 $name = DOMUtils::uncoerceName( $name );
53                 if ( $namespace === HTMLData::NS_HTML ) {
54                         $tagName = $name;
55                 } elseif ( $namespace === HTMLData::NS_SVG ) {
56                         $tagName = "svg $name";
57                 } elseif ( $namespace === HTMLData::NS_MATHML ) {
58                         $tagName = "math $name";
59                 } else {
60                         $tagName = $name;
61                 }
62                 $ret = "<$tagName>\n";
63                 $sortedAttrs = $attrs;
64                 ksort( $sortedAttrs, SORT_STRING );
65                 foreach ( $sortedAttrs as $attrName => $attr ) {
66                         $localName = DOMUtils::uncoerceName( $attr->localName );
67                         if ( $attr->namespaceURI === null
68                                 || isset( $attr->reallyNoNamespace )
69                         ) {
70                                 $prefix = '';
71                         } elseif ( isset( self::$attrNamespaces[$attr->namespaceURI] ) ) {
72                                 $prefix = self::$attrNamespaces[$attr->namespaceURI] . ' ';
73                         }
74                         $ret .= "  $prefix$localName=\"{$attr->value}\"\n";
75                 }
76                 if ( $contents !== null && $contents !== '' ) {
77                         $contents = preg_replace( '/^/m', '  ', $contents );
78                 } else {
79                         $contents = '';
80                 }
81                 if ( $namespace === HTMLData::NS_HTML && $name === 'template' ) {
82                         if ( $contents === '' ) {
83                                 $contents = "  content\n";
84                         } else {
85                                 $contents = "  content\n" . preg_replace( '/^/m', '  ', $contents );
86                         }
87                 }
88                 $ret .= $contents;
89                 return $ret;
90         }
91
92         public function comment( SerializerNode $parent, $text ) {
93                 return $this->formatComment( $text );
94         }
95
96         private function formatComment( $text ) {
97                 return "<!-- $text -->\n";
98         }
99
100         public function formatDOMNode( \DOMNode $node ) {
101                 $contents = '';
102                 if ( $node->firstChild ) {
103                         foreach ( $node->childNodes as $child ) {
104                                 $contents .= $this->formatDOMNode( $child );
105                         }
106                 }
107
108                 switch ( $node->nodeType ) {
109                 case XML_ELEMENT_NODE:
110                         return $this->formatDOMElement( $node, $contents );
111
112                 case XML_DOCUMENT_NODE:
113                 case XML_DOCUMENT_FRAG_NODE:
114                         return $contents;
115
116                 case XML_TEXT_NODE:
117                 case XML_CDATA_SECTION_NODE:
118                         return $this->formatCharacters( $node->data );
119
120                 case XML_COMMENT_NODE:
121                         return $this->formatComment( $node->data );
122
123                 case XML_DOCUMENT_TYPE_NODE:
124                         return $this->doctype( $node->name, $node->publicId, $node->systemId );
125
126                 case XML_PI_NODE:
127                 default:
128                         return '';
129                 }
130         }
131
132         public function formatDOMElement( \DOMElement $node, $content ) {
133                 $attrs = [];
134                 foreach ( $node->attributes as $attr ) {
135                         $prefix = null;
136                         switch ( $attr->namespaceURI ) {
137                         case HTMLData::NS_XML:
138                                 $prefix = 'xml';
139                                 $qName = 'xml:' . $attr->localName;
140                                 break;
141                         case HTMLData::NS_XMLNS:
142                                 if ( $attr->localName === 'xmlns' ) {
143                                         $qName = 'xmlns';
144                                 } else {
145                                         $prefix = 'xmlns';
146                                         $qName = 'xmlns:' . $attr->localName;
147                                 }
148                                 break;
149                         case HTMLData::NS_XLINK:
150                                 $prefix = 'xlink';
151                                 $qName = 'xlink:' . $attr->localName;
152                                 break;
153                         default:
154                                 if ( strlen( $attr->prefix ) ) {
155                                         $qName = $attr->prefix . ':' . $attr->localName;
156                                 } else {
157                                         $prefix = $attr->prefix;
158                                         $qName = $attr->localName;
159                                 }
160                         }
161
162                         $attrs[$qName] = new Attribute( $qName, $attr->namespaceURI, $prefix,
163                                 $attr->localName, $attr->value );
164                 }
165
166                 return $this->formatElement( $node->namespaceURI, $node->nodeName, $attrs, $content );
167         }
168 }