1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*/
namespace MediaWiki\Skin;
use MediaWiki\Output\OutputPage;
use MediaWiki\Parser\ParserOutputFlags;
/**
* @internal for use inside Skin and SkinTemplate classes only
* @unstable
*/
class SkinComponentTableOfContents implements SkinComponent {
/** @var OutputPage */
private $output;
public function __construct( OutputPage $output ) {
$this->output = $output;
}
/**
* Nests child sections within their parent sections.
*
* @param array $sections
* @param int $toclevel
* @return array
*/
private function getSectionsDataInternal( array $sections, int $toclevel = 1 ): array {
$data = [];
foreach ( $sections as $i => $section ) {
// Child section belongs to a higher parent.
if ( $section->tocLevel < $toclevel ) {
return $data;
}
// Set all the parent sections at the current top level.
if ( $section->tocLevel === $toclevel ) {
$childSections = $this->getSectionsDataInternal(
array_slice( $sections, $i + 1 ),
$toclevel + 1
);
$data[] = $section->toLegacy() + [
'array-sections' => $childSections,
'is-top-level-section' => $toclevel === 1,
'is-parent-section' => $childSections !== []
];
}
}
return $data;
}
/**
* Get table of contents template data
*
* Enriches section data by nesting child elements within parent elements
* such that the table of contents can be rendered in Mustache.
*
* For an example of how to render the data, see TableOfContents.mustache in
* the Vector skin.
*/
private function getTOCDataInternal(): array {
$tocData = $this->output->getTOCData();
// Return data only if TOC present T298796.
if ( $tocData === null ) {
return [];
}
// Respect __NOTOC__
if ( $this->output->getOutputFlag( ParserOutputFlags::NO_TOC ) ) {
return [];
}
$outputSections = $tocData->getSections();
return count( $outputSections ) > 0 ? [
'number-section-count' => count( $outputSections ),
'array-sections' => $this->getSectionsDataInternal( $outputSections, 1 ),
] : [];
}
/**
* @inheritDoc
*/
public function getTemplateData(): array {
return $this->getTOCDataInternal();
}
}
|