Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
DOMHandlerFactory
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 2
2756
0.00% covered (danger)
0.00%
0 / 1
 newFromTagHandler
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 1
1560
 getDOMHandler
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
182
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Html2Wt\DOMHandlers;
5
6use Wikimedia\Parsoid\DOM\DocumentFragment;
7use Wikimedia\Parsoid\DOM\Element;
8use Wikimedia\Parsoid\DOM\Node;
9use Wikimedia\Parsoid\Utils\DOMDataUtils;
10use Wikimedia\Parsoid\Utils\DOMUtils;
11use Wikimedia\Parsoid\Utils\WTUtils;
12
13/**
14 * Factory for picking the right DOMHandler for a DOM element.
15 * FIXME: memoize handlers, maybe?
16 */
17class DOMHandlerFactory {
18
19    /**
20     * Get the DOMHandler that's appropriate for serializing a HTML tag.
21     *
22     * Porting note: this is the equivalent of DOMHandlers.tagHandlers[tag].
23     * @param string $tag
24     * @return DOMHandler|null
25     */
26    public function newFromTagHandler( string $tag ): ?DOMHandler {
27        switch ( $tag ) {
28            case 'a':
29                return new AHandler();
30            case 'audio':
31                return new MediaHandler();
32            case 'b':
33                return new QuoteHandler( "'''" );
34            case 'body':
35                return new BodyHandler();
36            case 'br':
37                return new BRHandler();
38            case 'caption':
39                return new CaptionHandler();
40            case 'dd':
41                return new DDHandler(); // multi-line dt/dd
42            case 'dd_row':
43                return new DDHandler( 'row' ); // single-line dt/dd
44            case 'dl':
45                return new ListHandler( [ 'dt', 'dd' ] );
46            case 'dt':
47                return new DTHandler();
48            case 'figure':
49                return new FigureHandler();
50            case 'hr':
51                return new HRHandler();
52            case 'h1':
53                return new HeadingHandler( '=' );
54            case 'h2':
55                return new HeadingHandler( '==' );
56            case 'h3':
57                return new HeadingHandler( '===' );
58            case 'h4':
59                return new HeadingHandler( '====' );
60            case 'h5':
61                return new HeadingHandler( '=====' );
62            case 'h6':
63                return new HeadingHandler( '======' );
64            case 'i':
65                return new QuoteHandler( "''" );
66            case 'img':
67                return new ImgHandler();
68            case 'li':
69                return new LIHandler();
70            case 'link':
71                return new LinkHandler();
72            case 'meta':
73                return new MetaHandler();
74            case 'ol':
75                return new ListHandler( [ 'li' ] );
76            case 'p':
77                return new PHandler();
78            case 'pre':
79                return new PreHandler(); // Wikitext indent pre generated with leading space
80            case 'pre_html':
81                return new HTMLPreHandler(); // HTML pre
82            case 'span':
83                return new SpanHandler();
84            case 'table':
85                return new TableHandler();
86            case 'tbody':
87                return new JustChildrenHandler();
88            case 'td':
89                return new TDHandler();
90            case 'tfoot':
91                return new JustChildrenHandler();
92            case 'th':
93                return new THHandler();
94            case 'thead':
95                return new JustChildrenHandler();
96            case 'tr':
97                return new TRHandler();
98            case 'ul':
99                return new ListHandler( [ 'li' ] );
100            case 'video':
101                return new MediaHandler();
102            default:
103                return null;
104        }
105    }
106
107    /**
108     * Get a DOMHandler for an element node.
109     * @param ?Node $node
110     * @return DOMHandler
111     */
112    public function getDOMHandler( ?Node $node ): DOMHandler {
113        if ( $node instanceof DocumentFragment ) {
114            return new BodyHandler();
115        }
116
117        if ( !( $node instanceof Element ) ) {
118            return new DOMHandler();
119        }
120        '@phan-var Element $node';/** @var Element $node */
121
122        if ( WTUtils::isFirstEncapsulationWrapperNode( $node ) ) {
123            return new EncapsulatedContentHandler();
124        }
125
126        $dp = DOMDataUtils::getDataParsoid( $node );
127
128        // If available, use a specialized handler for serializing
129        // to the specialized syntactic form of the tag.
130        $handler = $this->newFromTagHandler( DOMUtils::nodeName( $node ) . '_' . ( $dp->stx ?? null ) );
131
132        // Unless a specialized handler is available, use the HTML handler
133        // for html-stx tags. But, <a> tags should never serialize as HTML.
134        if ( !$handler && ( $dp->stx ?? null ) === 'html' && DOMUtils::nodeName( $node ) !== 'a' ) {
135            return new FallbackHTMLHandler();
136        }
137
138        // If in a HTML table tag, serialize table tags in the table
139        // using HTML tags, instead of native wikitext tags.
140        if ( WTUtils::serializeChildTableTagAsHTML( $node ) ) {
141            return new FallbackHTMLHandler();
142        }
143
144        // If parent node is a list in html-syntax, then serialize
145        // list content in html-syntax rather than wiki-syntax.
146        if ( DOMUtils::isListItem( $node )
147             && DOMUtils::isList( $node->parentNode )
148             && WTUtils::isLiteralHTMLNode( $node->parentNode )
149        ) {
150            return new FallbackHTMLHandler();
151        }
152
153        // Pick the best available handler
154        return $handler ?: $this->newFromTagHandler( DOMUtils::nodeName( $node ) ) ?: new FallbackHTMLHandler();
155    }
156
157}