Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ListHandler
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 4
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 handle
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
42
 before
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
90
 after
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\Html2Wt\DOMHandlers;
5
6use Wikimedia\Parsoid\DOM\Element;
7use Wikimedia\Parsoid\DOM\Node;
8use Wikimedia\Parsoid\Html2Wt\SerializerState;
9use Wikimedia\Parsoid\Utils\DiffDOMUtils;
10use Wikimedia\Parsoid\Utils\DOMCompat;
11use Wikimedia\Parsoid\Utils\DOMUtils;
12use Wikimedia\Parsoid\Utils\WTUtils;
13
14class ListHandler extends DOMHandler {
15
16    /** @var string[] List of tag names which van be first children of the list */
17    public $firstChildNames;
18
19    /**
20     * @param string[] $firstChildNames List of tag names which van be first children of the list
21     */
22    public function __construct( array $firstChildNames ) {
23        parent::__construct( true );
24        $this->firstChildNames = $firstChildNames;
25    }
26
27    /** @inheritDoc */
28    public function handle(
29        Element $node, SerializerState $state, bool $wrapperUnmodified = false
30    ): ?Node {
31        // Disable single-line context here so that separators aren't
32        // suppressed between nested list elements.
33        $state->singleLineContext->disable();
34
35        $firstChildElt = DiffDOMUtils::firstNonSepChild( $node );
36
37        // Skip builder-inserted wrappers
38        // Ex: <ul><s auto-inserted-start-and-end-><li>..</li><li>..</li></s>...</ul>
39        // output from: <s>\n*a\n*b\n*c</s>
40        while ( $firstChildElt && $this->isBuilderInsertedElt( $firstChildElt ) ) {
41            $firstChildElt = DiffDOMUtils::firstNonSepChild( $firstChildElt );
42        }
43
44        if ( !$firstChildElt || !in_array( DOMCompat::nodeName( $firstChildElt ), $this->firstChildNames, true )
45            || WTUtils::isLiteralHTMLNode( $firstChildElt )
46        ) {
47            $state->emitChunk( $this->getListBullets( $state, $node ), $node );
48        }
49
50        $liHandler = static function ( $state, $text, $opts ) use ( $node ) {
51            return $state->serializer->wteHandlers->liHandler( $node, $state, $text, $opts );
52        };
53        $state->serializeChildren( $node, $liHandler );
54        $state->singleLineContext->pop();
55        return $node->nextSibling;
56    }
57
58    /** @inheritDoc */
59    public function before( Element $node, Node $otherNode, SerializerState $state ): array {
60        if ( DOMUtils::atTheTop( $otherNode ) ) {
61            return [ 'min' => 0, 'max' => 0 ];
62        }
63
64        // node is in a list & otherNode has the same list parent
65        // => exactly 1 newline
66        if ( DOMUtils::isListItem( $node->parentNode ) && $otherNode->parentNode === $node->parentNode ) {
67            return [ 'min' => 1, 'max' => 1 ];
68        }
69
70        // A list in a block node (<div>, <td>, etc) doesn't need a leading empty line
71        // if it is the first non-separator child (ex: <div><ul>...</div>)
72        if (
73            DOMUtils::isWikitextBlockNode( $node->parentNode ) &&
74            DiffDOMUtils::firstNonSepChild( $node->parentNode ) === $node
75        ) {
76            return [ 'min' => 1, 'max' => 2 ];
77        } elseif ( DOMUtils::isFormattingElt( $otherNode ) ) {
78            return [ 'min' => 1, 'max' => 1 ];
79        } else {
80            return [
81                'min' => WTUtils::isNewElt( $node ) && !WTUtils::isMarkerAnnotation( $otherNode )
82                    ? 2 : 1,
83                'max' => 2
84            ];
85        }
86    }
87
88    /** @inheritDoc */
89    public function after( Element $node, Node $otherNode, SerializerState $state ): array {
90        return $this->wtListEOL( $node, $otherNode );
91    }
92
93}