Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
60.61% covered (warning)
60.61%
20 / 33
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
VectorComponentTableOfContents
60.61% covered (warning)
60.61%
20 / 33
33.33% covered (danger)
33.33%
1 / 3
11.91
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 isPinned
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTemplateData
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2namespace MediaWiki\Skins\Vector\Components;
3
4use MediaWiki\Config\Config;
5use MediaWiki\Skins\Vector\Constants;
6use MediaWiki\Skins\Vector\FeatureManagement\FeatureManager;
7use MessageLocalizer;
8
9/**
10 * VectorComponentTableOfContents component
11 */
12class VectorComponentTableOfContents implements VectorComponent {
13
14    /** @var array */
15    private $tocData;
16
17    /** @var MessageLocalizer */
18    private $localizer;
19
20    /** @var bool */
21    private $isPinned;
22
23    /** @var Config */
24    private $config;
25
26    /** @var VectorComponentPinnableHeader */
27    private $pinnableHeader;
28
29    /** @var string */
30    public const ID = 'vector-toc';
31
32    /**
33     * @param array $tocData
34     * @param MessageLocalizer $localizer
35     * @param Config $config
36     * @param FeatureManager $featureManager
37     */
38    public function __construct(
39        array $tocData,
40        MessageLocalizer $localizer,
41        Config $config,
42        FeatureManager $featureManager
43    ) {
44        $this->tocData = $tocData;
45        $this->localizer = $localizer;
46        // FIXME: isPinned is no longer accurate because the appearance menu uses client preferences
47        $this->isPinned = $featureManager->isFeatureEnabled( Constants::FEATURE_TOC_PINNED );
48        $this->config = $config;
49        $this->pinnableHeader = new VectorComponentPinnableHeader(
50            $this->localizer,
51            $this->isPinned,
52            self::ID,
53            'toc-pinned',
54            false,
55            'h2'
56        );
57    }
58
59    /**
60     * @return bool
61     */
62    public function isPinned(): bool {
63        return $this->isPinned;
64    }
65
66    /**
67     * In tableOfContents.js we have tableOfContents::getTableOfContentsSectionsData(),
68     * that yields the same result as this function, please make sure to keep them in sync.
69     * @inheritDoc
70     */
71    public function getTemplateData(): array {
72        $sections = $this->tocData[ 'array-sections' ] ?? [];
73        if ( !$sections ) {
74            return [];
75        }
76        // Populate button labels for collapsible TOC sections
77        foreach ( $sections as &$section ) {
78            if ( $section['is-top-level-section'] && $section['is-parent-section'] ) {
79                $section['vector-button-label'] =
80                    $this->localizer->msg( 'vector-toc-toggle-button-label' )
81                        ->rawParams( $section['line'] )
82                        ->escaped();
83            }
84        }
85        $this->tocData[ 'array-sections' ] = $sections;
86
87        $pinnableElement = new VectorComponentPinnableElement( self::ID );
88
89        return $pinnableElement->getTemplateData() +
90            array_merge( $this->tocData, [
91            'vector-is-collapse-sections-enabled' =>
92                count( $this->tocData['array-sections'] ) > 3 &&
93                $this->tocData[ 'number-section-count'] >= $this->config->get(
94                    'VectorTableOfContentsCollapseAtCount'
95                ),
96            'data-pinnable-header' => $this->pinnableHeader->getTemplateData(),
97        ] );
98    }
99}