xref: /plugin/combo/syntax/navbarcollapse.php (revision aa3cb38f16c718b4f409afba33b2d5efdbe0760a)
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    /**
58     * We don't accept link as substition
59     * @param string $mode
60     * @return bool
61     */
62//    public function accepts($mode)
63//    {
64//        $position = strpos($mode, 'link');
65//        if ($position === false){
66//            return parent::accepts($mode);
67//        } else {
68//            return false;
69//        }
70//
71//    }
72
73
74    /**
75     * How Dokuwiki will add P element
76     *
77     * * 'normal' - The plugin can be used inside paragraphs
78     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
79     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
80     *
81     * @see DokuWiki_Syntax_Plugin::getPType()
82     */
83    function getPType()
84    {
85        return 'normal';
86    }
87
88    /**
89     * @see Doku_Parser_Mode::getSort()
90     *
91     * the mode with the lowest sort number will win out
92     * the container (parent) must then have a lower number than the child
93     */
94    function getSort()
95    {
96        return 100;
97    }
98
99    /**
100     * Create a pattern that will called this plugin
101     *
102     * @param string $mode
103     * @see Doku_Parser_Mode::connectTo()
104     */
105    function connectTo($mode)
106    {
107        // Only inside a navbar
108        if ($mode == PluginUtility::getModeForComponent(syntax_plugin_combo_navbar::TAG)) {
109            $pattern = PluginUtility::getContainerTagPattern(self::TAG);
110            $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
111        }
112
113    }
114
115    public function postConnect()
116    {
117
118        $this->Lexer->addExitPattern('</' . self::TAG . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
119
120    }
121
122    /**
123     *
124     * The handle function goal is to parse the matched syntax through the pattern function
125     * and to return the result for use in the renderer
126     * This result is always cached until the page is modified.
127     * @param string $match
128     * @param int $state
129     * @param int $pos
130     * @param Doku_Handler $handler
131     * @return array|bool
132     * @see DokuWiki_Syntax_Plugin::handle()
133     *
134     */
135    function handle($match, $state, $pos, Doku_Handler $handler)
136    {
137
138        switch ($state) {
139
140            case DOKU_LEXER_ENTER:
141
142                $tagAttributes = PluginUtility::getTagAttributes($match);
143                return array($state, $tagAttributes);
144
145            case DOKU_LEXER_UNMATCHED :
146
147                return array($state, $match);
148
149
150            case DOKU_LEXER_EXIT :
151
152                return array($state, '');
153
154
155        }
156
157        return array();
158
159    }
160
161    /**
162     * Render the output
163     * @param string $format
164     * @param Doku_Renderer $renderer
165     * @param array $data - what the function handle() return'ed
166     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
167     * @see DokuWiki_Syntax_Plugin::render()
168     *
169     *
170     */
171    function render($format, Doku_Renderer $renderer, $data)
172    {
173        list($state, $payload) = $data;
174        switch ($format) {
175            case 'xhtml':
176                /** @var Doku_Renderer_xhtml $renderer */
177
178                switch ($state) {
179
180                    case DOKU_LEXER_ENTER :
181
182                        $attributes = $payload;
183
184                        // The button is the hamburger menu that will be shown
185                        $idElementToCollapse = 'navbarcollapse';
186                        $renderer->doc .= '<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#' . $idElementToCollapse . '" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation"';
187                        if (array_key_exists("order", $attributes)) {
188                            $renderer->doc .= ' style="order:' . $attributes["order"];
189                            unset($attributes["order"]);
190                        }
191                        $renderer->doc .= '"><span class="navbar-toggler-icon"></span></button>' . DOKU_LF;
192
193
194                        $classValue = "collapse navbar-collapse";
195                        if (array_key_exists("class", $attributes)) {
196                            $attributes["class"] .= " {$classValue}";
197                        } else {
198                            $attributes["class"] = "{$classValue}";
199                        }
200                        $renderer->doc .= '<div id="' . $idElementToCollapse . '" '.PluginUtility::array2HTMLAttributes($attributes).'>';
201
202                        // All element below will collapse
203                        break;
204
205                    case DOKU_LEXER_UNMATCHED:
206                        $renderer->doc .= NavBarUtility::text(PluginUtility::escape($payload));
207                        break;
208
209
210                    case DOKU_LEXER_EXIT :
211
212                        $renderer->doc .= '</div>' . DOKU_LF;
213                        break;
214                }
215                return true;
216
217        }
218        return false;
219    }
220
221
222    public static function getElementName()
223    {
224        return PluginUtility::getTagName(get_called_class());
225    }
226
227
228}
229