xref: /plugin/combo/syntax/navbarcollapse.php (revision e3d0019c6b36768036e5b89a5459073196493345)
1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13use ComboStrap\HtmlUtility;
14use ComboStrap\LinkUtility;
15use ComboStrap\NavBarUtility;
16use ComboStrap\PluginUtility;
17
18
19require_once(__DIR__ . '/../class/PluginUtility.php');
20require_once(__DIR__ . '/../class/NavBarUtility.php');
21
22
23/**
24 *
25 * See https://getbootstrap.com/docs/4.0/components/collapse/
26 *
27 * The name of the class must follow a pattern (don't change it) ie syntax_plugin_PluginName_ComponentName
28 */
29class syntax_plugin_combo_navbarcollapse extends DokuWiki_Syntax_Plugin
30{
31    const TAG = 'collapse';
32    const COMPONENT = 'navbarcollapse';
33
34    /**
35     * Syntax Type.
36     *
37     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
38     * @see DokuWiki_Syntax_Plugin::getType()
39     */
40    function getType()
41    {
42        return 'container';
43    }
44
45    /**
46     * @return array
47     * Allow which kind of plugin inside
48     *
49     * No one of array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
50     * because we manage self the content and we call self the parser
51     */
52    public function getAllowedTypes()
53    {
54        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
55    }
56
57    public function accepts($mode)
58    {
59        $accept = true;
60
61        if (!$this->getConf(syntax_plugin_combo_preformatted::CONF_PREFORMATTED_ENABLE)) {
62            $accept = PluginUtility::disablePreformatted($mode);
63        }
64
65        // P element are not welcome in a navbar
66        if ($mode == "eol") {
67            $accept = false;
68        }
69
70        return $accept;
71
72    }
73
74
75    /**
76     * How Dokuwiki will add P element
77     *
78     * * 'normal' - The plugin can be used inside paragraphs
79     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
80     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
81     *
82     * @see DokuWiki_Syntax_Plugin::getPType()
83     */
84    function getPType()
85    {
86        return 'normal';
87    }
88
89    /**
90     * @see Doku_Parser_Mode::getSort()
91     *
92     * the mode with the lowest sort number will win out
93     * the container (parent) must then have a lower number than the child
94     */
95    function getSort()
96    {
97        return 100;
98    }
99
100    /**
101     * Create a pattern that will called this plugin
102     *
103     * @param string $mode
104     * @see Doku_Parser_Mode::connectTo()
105     */
106    function connectTo($mode)
107    {
108        // Only inside a navbar
109        if ($mode == PluginUtility::getModeForComponent(syntax_plugin_combo_navbar::TAG)) {
110            $pattern = PluginUtility::getContainerTagPattern(self::TAG);
111            $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
112        }
113
114    }
115
116    public function postConnect()
117    {
118
119        $this->Lexer->addExitPattern('</' . self::TAG . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
120
121    }
122
123    /**
124     *
125     * The handle function goal is to parse the matched syntax through the pattern function
126     * and to return the result for use in the renderer
127     * This result is always cached until the page is modified.
128     * @param string $match
129     * @param int $state
130     * @param int $pos
131     * @param Doku_Handler $handler
132     * @return array|bool
133     * @see DokuWiki_Syntax_Plugin::handle()
134     *
135     */
136    function handle($match, $state, $pos, Doku_Handler $handler)
137    {
138
139        switch ($state) {
140
141            case DOKU_LEXER_ENTER:
142
143                $tagAttributes = PluginUtility::getTagAttributes($match);
144                return array($state, $tagAttributes);
145
146            case DOKU_LEXER_UNMATCHED :
147
148                return array($state, $match);
149
150
151            case DOKU_LEXER_EXIT :
152
153                return array($state, '');
154
155
156        }
157
158        return array();
159
160    }
161
162    /**
163     * Render the output
164     * @param string $format
165     * @param Doku_Renderer $renderer
166     * @param array $data - what the function handle() return'ed
167     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
168     * @see DokuWiki_Syntax_Plugin::render()
169     *
170     *
171     */
172    function render($format, Doku_Renderer $renderer, $data)
173    {
174        list($state, $payload) = $data;
175        switch ($format) {
176            case 'xhtml':
177                /** @var Doku_Renderer_xhtml $renderer */
178
179                switch ($state) {
180
181                    case DOKU_LEXER_ENTER :
182
183                        $attributes = $payload;
184
185                        // The button is the hamburger menu that will be shown
186                        $idElementToCollapse = 'navbarcollapse';
187                        $renderer->doc .= '<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#' . $idElementToCollapse . '" aria-controls="' . $idElementToCollapse . '" aria-expanded="false" aria-label="Toggle navigation"';
188                        if (array_key_exists("order", $attributes)) {
189                            $renderer->doc .= ' style="order:' . $attributes["order"] . '"';
190                            unset($attributes["order"]);
191                        }
192                        $renderer->doc .= '>' . DOKU_LF;
193                        $renderer->doc .= '<span class="navbar-toggler-icon"></span>' . DOKU_LF;
194                        $renderer->doc .= '</button>' . DOKU_LF;
195
196
197                        $classValue = "collapse navbar-collapse";
198                        if (array_key_exists("class", $attributes)) {
199                            $attributes["class"] .= " {$classValue}";
200                        } else {
201                            $attributes["class"] = "{$classValue}";
202                        }
203                        $renderer->doc .= '<div id="' . $idElementToCollapse . '" ' . PluginUtility::array2HTMLAttributes($attributes) . '>';
204
205                        // All element below will collapse
206                        break;
207
208                    case DOKU_LEXER_UNMATCHED:
209                        $renderer->doc .= NavBarUtility::text(PluginUtility::escape($payload));
210                        break;
211
212
213                    case DOKU_LEXER_EXIT :
214
215                        $renderer->doc .= '</div>' . DOKU_LF;
216                        break;
217                }
218                return true;
219
220        }
221        return false;
222    }
223
224
225    public static function getElementName()
226    {
227        return PluginUtility::getTagName(get_called_class());
228    }
229
230
231}
232