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