forked from oetterer/BootstrapComponents
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNestingController.php
More file actions
133 lines (122 loc) · 3.88 KB
/
Copy pathNestingController.php
File metadata and controls
133 lines (122 loc) · 3.88 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
* Contains the class handling the component nesting stack.
*
* @copyright (C) 2018, Tobias Oetterer, Paderborn University
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
*
* This file is part of the MediaWiki extension BootstrapComponents.
* The BootstrapComponents extension 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 3 of the License, or
* (at your option) any later version.
*
* The BootstrapComponents extension 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, see <https://www.gnu.org/licenses/>.
*
* @file
* @ingroup BootstrapComponents
* @author Tobias Oetterer
*/
namespace BootstrapComponents;
use \MWException;
/**
* Class NestingController
*
* Takes care of some things that occur when nesting bootstrap components
*
* @since 1.0
*/
class NestingController {
/**
* List of ids already in use in the context of the bootstrap components.
* Key is of this array is the component name, value is the next usable id.
*
* @var array $autoincrementPerComponent
*/
private $autoincrementPerComponent;
/**
* Holds information about the bootstrap component stack, so that components
* can get information about their parent "nest".
*
* Consists of elements of type {@see Nestable}.
*
* @var array $componentStack
*/
private $componentStack;
/**
* NestingController constructor.
*
* Do not instantiate directly, but use {@see ApplicationFactory::getNestingController} instead.
*
* @see ApplicationFactory::getNestingController
*/
public function __construct() {
$this->autoincrementPerComponent = [];
$this->componentStack = [];
}
/**
* Signals the closing of a bootstrap component.
*
* @param string|false $id id of the current object we are trying to close
*
* @throws MWException if current and closing component is different
*/
public function close( $id ) {
$current = $this->getCurrentElement();
if ( !$current ) {
throw new MWException( 'Nesting error. Tried to close an empty stack.' );
}
if ( $id === false || ($current->getId() != $id) ) {
throw new MWException( 'Nesting error. Trying to close a component that is not the currently open one.' );
}
array_pop( $this->componentStack );
}
/**
* Generates an id not in use within any bootstrap component on this page yet.
*
* @param string $componentName
*
* @return string
*/
public function generateUniqueId( $componentName ) {
if ( !isset( $this->autoincrementPerComponent[$componentName] ) ) {
$this->autoincrementPerComponent[$componentName] = 0;
}
return 'bsc_' . $componentName . '_' . ($this->autoincrementPerComponent[$componentName]++);
}
/**
* Returns a reference to the last opened component.
*
* @return false|NestableInterface
*/
public function getCurrentElement() {
return end( $this->componentStack );
}
/**
* Returns the size of the stack.
*
* @return int
*/
public function getStackSize() {
return count( $this->componentStack );
}
/**
* Signals the opening of a bootstrap component (thus letting the nc put the nestable component on its stack).
*
* @param NestableInterface $nestable
*
* @throws MWException when open is called with an invalid object
*/
public function open( &$nestable ) {
if ( !$nestable instanceof NestableInterface ) {
throw new MWException( 'Nesting error. Trying to put an object other than a Component an the nesting stack.' );
}
array_push( $this->componentStack, $nestable );
}
}