Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
PreHandler
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 6
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 handle
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
12
 before
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 after
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 firstChild
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 lastChild
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\DOMCompat;
10use Wikimedia\Parsoid\Utils\DOMDataUtils;
11use Wikimedia\Parsoid\Utils\PHPUtils;
12use Wikimedia\Parsoid\Utils\Utils;
13
14class PreHandler extends DOMHandler {
15
16    public function __construct() {
17        parent::__construct( false );
18    }
19
20    /** @inheritDoc */
21    public function handle(
22        Element $node, SerializerState $state, bool $wrapperUnmodified = false
23    ): ?Node {
24        // Handle indent pre
25
26        // XXX: Use a pre escaper?
27        $content = $state->serializeIndentPreChildrenToString( $node );
28        // Strip (only the) trailing newline
29        $trailingNL = str_ends_with( $content, "\n" ) ? "\n" : '';
30        if ( $trailingNL !== '' ) {
31            $content = substr( $content, 0, -1 );
32        }
33
34        // Insert indentation
35        $solRE = '/'
36            . '(\n('
37            // SSS FIXME: What happened to the includeonly seen
38            // in wts.separators.js?
39            . PHPUtils::reStrip( Utils::COMMENT_REGEXP )
40            . ')*)'
41        . '/';
42        $content = ' ' . preg_replace( $solRE, '$1 ', $content );
43
44        // But skip "empty lines" (lines with 1+ comment and
45        // optional whitespace) since empty-lines sail through all
46        // handlers without being affected.
47        //
48        // See empty_line_with_comments rule in pegTokenizer.pegjs
49        //
50        // We could use 'split' to split content into lines and
51        // selectively add indentation, but the code will get
52        // unnecessarily complex for questionable benefits. So, going
53        // this route for now.
54        $emptyLinesRE = '/'
55            // This space comes from what we inserted earlier
56            . '(^|\n) '
57            . '((?:'
58            . '[ \t]*'
59            . PHPUtils::reStrip( Utils::COMMENT_REGEXP )
60            . '[ \t]*'
61            . ')+)'
62            . '(?=\n|$)'
63        . '/D';
64        $content = preg_replace( $emptyLinesRE, '$1$2', $content, 1 );
65
66        $state->emitChunk( $content, $node );
67
68        // Preserve separator source
69        $state->appendSep( $trailingNL );
70        return $node->nextSibling;
71    }
72
73    /** @inheritDoc */
74    public function before( Element $node, Node $otherNode, SerializerState $state ): array {
75        if ( $otherNode instanceof Element // for static analyzers
76            && DOMCompat::nodeName( $otherNode ) === 'pre'
77            && ( DOMDataUtils::getDataParsoid( $otherNode )->stx ?? null ) !== 'html'
78        ) {
79            return [ 'min' => 2 ];
80        } else {
81            return [ 'min' => 1 ];
82        }
83    }
84
85    /** @inheritDoc */
86    public function after( Element $node, Node $otherNode, SerializerState $state ): array {
87        if ( $otherNode instanceof Element // for static analyzers
88            && DOMCompat::nodeName( $otherNode ) === 'pre'
89            && ( DOMDataUtils::getDataParsoid( $otherNode )->stx ?? null ) !== 'html'
90        ) {
91            return [ 'min' => 2 ];
92        } else {
93            return [ 'min' => 1 ];
94        }
95    }
96
97    /** @inheritDoc */
98    public function firstChild( Node $node, Node $otherNode, SerializerState $state ): array {
99        return [];
100    }
101
102    /** @inheritDoc */
103    public function lastChild( Node $node, Node $otherNode, SerializerState $state ): array {
104        return [];
105    }
106
107}