'xml', HTMLData::NS_XLINK => 'xlink', HTMLData::NS_XMLNS => 'xmlns', ]; public function startDocument( $fragmentNamespace, $fragmentName ) { return ''; } public function doctype( $name, $public, $system ) { $ret = "\n"; return $ret; } public function characters( SerializerNode $parent, $text, $start, $length ) { return $this->formatCharacters( substr( $text, $start, $length ) ); } private function formatCharacters( $text ) { return '"' . str_replace( "\n", "", $text ) . "\"\n"; } public function element( SerializerNode $parent, SerializerNode $node, $contents ) { return $this->formatElement( $node->namespace, $node->name, $node->attrs->getObjects(), $contents ); } private function formatElement( $namespace, $name, $attrs, $contents ) { $name = DOMUtils::uncoerceName( $name ); if ( $namespace === HTMLData::NS_HTML ) { $tagName = $name; } elseif ( $namespace === HTMLData::NS_SVG ) { $tagName = "svg $name"; } elseif ( $namespace === HTMLData::NS_MATHML ) { $tagName = "math $name"; } else { $tagName = $name; } $ret = "<$tagName>\n"; $sortedAttrs = $attrs; ksort( $sortedAttrs, SORT_STRING ); foreach ( $sortedAttrs as $attrName => $attr ) { $localName = DOMUtils::uncoerceName( $attr->localName ); if ( $attr->namespaceURI === null || isset( $attr->reallyNoNamespace ) ) { $prefix = ''; } elseif ( isset( self::$attrNamespaces[$attr->namespaceURI] ) ) { $prefix = self::$attrNamespaces[$attr->namespaceURI] . ' '; } $ret .= " $prefix$localName=\"{$attr->value}\"\n"; } if ( $contents !== null && $contents !== '' ) { $contents = preg_replace( '/^/m', ' ', $contents ); } else { $contents = ''; } if ( $namespace === HTMLData::NS_HTML && $name === 'template' ) { if ( $contents === '' ) { $contents = " content\n"; } else { $contents = " content\n" . preg_replace( '/^/m', ' ', $contents ); } } $ret .= $contents; return $ret; } public function comment( SerializerNode $parent, $text ) { return $this->formatComment( $text ); } private function formatComment( $text ) { return "\n"; } public function formatDOMNode( \DOMNode $node ) { $contents = ''; if ( $node->firstChild ) { foreach ( $node->childNodes as $child ) { $contents .= $this->formatDOMNode( $child ); } } switch ( $node->nodeType ) { case XML_ELEMENT_NODE: return $this->formatDOMElement( $node, $contents ); case XML_DOCUMENT_NODE: case XML_DOCUMENT_FRAG_NODE: return $contents; case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: return $this->formatCharacters( $node->data ); case XML_COMMENT_NODE: return $this->formatComment( $node->data ); case XML_DOCUMENT_TYPE_NODE: return $this->doctype( $node->name, $node->publicId, $node->systemId ); case XML_PI_NODE: default: return ''; } } public function formatDOMElement( \DOMElement $node, $content ) { $attrs = []; foreach ( $node->attributes as $attr ) { $prefix = null; switch ( $attr->namespaceURI ) { case HTMLData::NS_XML: $prefix = 'xml'; $qName = 'xml:' . $attr->localName; break; case HTMLData::NS_XMLNS: if ( $attr->localName === 'xmlns' ) { $qName = 'xmlns'; } else { $prefix = 'xmlns'; $qName = 'xmlns:' . $attr->localName; } break; case HTMLData::NS_XLINK: $prefix = 'xlink'; $qName = 'xlink:' . $attr->localName; break; default: if ( strlen( $attr->prefix ) ) { $qName = $attr->prefix . ':' . $attr->localName; } else { $prefix = $attr->prefix; $qName = $attr->localName; } } $attrs[$qName] = new Attribute( $qName, $attr->namespaceURI, $prefix, $attr->localName, $attr->value ); } return $this->formatElement( $node->namespaceURI, $node->nodeName, $attrs, $content ); } }