1<?php
2/**
3 * DokuWiki Syntax Plugin Web Component.
4 *
5 */
6if (!defined('DOKU_INC')) {
7    die();
8}
9
10require_once(__DIR__ . '/../webcomponent.php');
11
12/**
13 * All DokuWiki plugins to extend the parser/rendering mechanism
14 * need to inherit from this class
15 *
16 * The name of the class must follow a pattern (don't change it)
17 * ie:
18 *    syntax_plugin_PluginName_ComponentName
19 */
20class syntax_plugin_webcomponent_collapse extends DokuWiki_Syntax_Plugin
21{
22
23
24    /**
25     * Syntax Type.
26     *
27     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
28     * @see DokuWiki_Syntax_Plugin::getType()
29     */
30    function getType()
31    {
32        return 'container';
33    }
34
35    /**
36     * @return array
37     * Allow which kind of plugin inside
38     * All
39     */
40    public function getAllowedTypes()
41    {
42        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
43    }
44
45    /**
46     * How Dokuwiki will add P element
47     *
48     * * 'normal' - The plugin can be used inside paragraphs
49     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
50     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
51     *
52     * @see DokuWiki_Syntax_Plugin::getPType()
53     */
54    function getPType()
55    {
56        return 'block';
57    }
58
59    /**
60     * @see Doku_Parser_Mode::getSort()
61     *
62     * the mode with the lowest sort number will win out
63     * the container (parent) must then have a lower number than the child
64     */
65    function getSort()
66    {
67        return 100;
68    }
69
70    /**
71     * Create a pattern that will called this plugin
72     *
73     * @see Doku_Parser_Mode::connectTo()
74     * @param string $mode
75     */
76    function connectTo($mode)
77    {
78
79        $pattern = webcomponent::getLookAheadPattern(self::getElementName());
80        $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent());
81
82    }
83
84    public function postConnect()
85    {
86
87        $this->Lexer->addExitPattern('</' . self::getElementName() . '>', 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent());
88
89    }
90
91    /**
92     *
93     * The handle function goal is to parse the matched syntax through the pattern function
94     * and to return the result for use in the renderer
95     * This result is always cached until the page is modified.
96     * @see DokuWiki_Syntax_Plugin::handle()
97     *
98     * @param string $match
99     * @param int $state
100     * @param int $pos
101     * @param Doku_Handler $handler
102     * @return array|bool
103     */
104    function handle($match, $state, $pos, Doku_Handler $handler)
105    {
106
107        switch ($state) {
108
109            case DOKU_LEXER_ENTER:
110
111                // Suppress the component name
112                $match = utf8_substr($match, strlen(self::getElementName()) + 1, -1);
113                $parameters = webcomponent::parseMatch($match);
114                return array($state, $parameters);
115
116            case DOKU_LEXER_EXIT :
117
118                return array($state, '');
119
120
121        }
122
123        return array();
124
125    }
126
127    /**
128     * Render the output
129     * @see DokuWiki_Syntax_Plugin::render()
130     *
131     * @param string $mode
132     * @param Doku_Renderer $renderer
133     * @param array $data - what the function handle() return'ed
134     * @return bool
135     */
136    function render($mode, Doku_Renderer $renderer, $data)
137    {
138
139        if ($mode == 'xhtml') {
140
141            /** @var Doku_Renderer_xhtml $renderer */
142            list($state, $parameters) = $data;
143            switch ($state) {
144
145                case DOKU_LEXER_ENTER :
146
147                    // The button is the hamburger menu that will be shown
148                    $idElementToCollapse ='navbarcollapse';
149                    $renderer->doc .= '<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#'.$idElementToCollapse.'" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation"';
150                    if (array_key_exists("order", $parameters)) {
151                        $renderer->doc .= ' style="order:' . $parameters["order"];
152                    }
153                    $renderer->doc .= '"><span class="navbar-toggler-icon"></span></button>' . DOKU_LF
154                        . '<div id="'.$idElementToCollapse.'" class="collapse navbar-collapse">';
155                    // All element below will collapse
156                    break;
157
158                case DOKU_LEXER_EXIT :
159
160                    $renderer->doc .= '</div>' . DOKU_LF;
161                    break;
162            }
163            return true;
164        }
165        return false;
166    }
167
168
169    public static function getElementName()
170    {
171        return webcomponent::getTagName(get_called_class());
172    }
173
174
175}
176