xref: /plugin/combo/syntax/tooltip.php (revision 8aa9d0e6721e371c683ed30933db9b4f2450a251)
1<?php
2
3
4use ComboStrap\SnippetManager;
5use ComboStrap\PluginUtility;
6use ComboStrap\Tag;
7
8if (!defined('DOKU_INC')) die();
9
10/**
11 * Class syntax_plugin_combo_tooltip
12 * Implementation of a tooltip
13 */
14class syntax_plugin_combo_tooltip extends DokuWiki_Syntax_Plugin
15{
16
17    const TAG = "tooltip";
18    const TEXT_ATTRIBUTE = "text";
19    const POSITION_ATTRIBUTE = "position";
20
21
22    /**
23     * tooltip is used also in page protection
24     */
25    public static function addToolTipSnippetIfNeeded()
26    {
27        $script = "window.addEventListener('load', function () { jQuery('[data-toggle=\"tooltip\"]').tooltip() })";
28        PluginUtility::getSnippetManager()->upsertJavascriptForBar(self::TAG, $script);
29    }
30
31
32    /**
33     * Syntax Type.
34     *
35     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
36     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
37     * @see DokuWiki_Syntax_Plugin::getType()
38     */
39    function getType()
40    {
41        return 'container';
42    }
43
44    /**
45     * How Dokuwiki will add P element
46     *
47     *  * 'normal' - The plugin can be used inside paragraphs (inline)
48     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
49     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
50     *
51     * @see DokuWiki_Syntax_Plugin::getPType()
52     * @see https://www.dokuwiki.org/devel:syntax_plugins#ptype
53     */
54    function getPType()
55    {
56        return 'normal';
57    }
58
59    /**
60     * @return array
61     * Allow which kind of plugin inside
62     *
63     * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
64     * because we manage self the content and we call self the parser
65     *
66     * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php
67     */
68    function getAllowedTypes()
69    {
70        return array('baseonly', 'container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
71    }
72
73    function getSort()
74    {
75        return 201;
76    }
77
78
79    function connectTo($mode)
80    {
81
82        $pattern = PluginUtility::getContainerTagPattern(self::TAG);
83        $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
84
85    }
86
87    function postConnect()
88    {
89
90        $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent()));
91
92    }
93
94    /**
95     *
96     * The handle function goal is to parse the matched syntax through the pattern function
97     * and to return the result for use in the renderer
98     * This result is always cached until the page is modified.
99     * @param string $match
100     * @param int $state
101     * @param int $pos - byte position in the original source file
102     * @param Doku_Handler $handler
103     * @return array|bool
104     * @see DokuWiki_Syntax_Plugin::handle()
105     *
106     */
107    function handle($match, $state, $pos, Doku_Handler $handler)
108    {
109
110        switch ($state) {
111
112            case DOKU_LEXER_ENTER :
113                $attributes = PluginUtility::getTagAttributes($match);
114
115                return array(
116                    PluginUtility::STATE => $state,
117                    PluginUtility::ATTRIBUTES => $attributes
118                );
119
120            case DOKU_LEXER_UNMATCHED :
121                return array(
122                    PluginUtility::STATE => $state,
123                    PluginUtility::PAYLOAD => PluginUtility::escape($match)
124                );
125
126            case DOKU_LEXER_EXIT :
127
128                $tag = new Tag(self::TAG, array(), $state, $handler);
129
130                return array(
131                    PluginUtility::STATE => $state,
132                    PluginUtility::ATTRIBUTES => $tag->getOpeningTag()->getAttributes()
133                );
134
135
136        }
137        return array();
138
139    }
140
141    /**
142     * Render the output
143     * @param string $format
144     * @param Doku_Renderer $renderer
145     * @param array $data - what the function handle() return'ed
146     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
147     * @see DokuWiki_Syntax_Plugin::render()
148     *
149     *
150     */
151    function render($format, Doku_Renderer $renderer, $data)
152    {
153        if ($format == 'xhtml') {
154
155            /** @var Doku_Renderer_xhtml $renderer */
156            $state = $data[PluginUtility::STATE];
157            switch ($state) {
158
159                case DOKU_LEXER_UNMATCHED:
160                    $renderer->doc .= $data[PluginUtility::PAYLOAD];
161                    break;
162                case DOKU_LEXER_ENTER :
163                    $attributes = $data[PluginUtility::ATTRIBUTES];
164
165                    if (isset($attributes[self::TEXT_ATTRIBUTE])) {
166                        $position = "top";
167                        if (isset($attributes[self::POSITION_ATTRIBUTE])) {
168                            $position = $attributes[self::POSITION_ATTRIBUTE];
169                        }
170                        $renderer->doc .= "<span class=\"d-inline-block\" tabindex=\"0\" data-toggle=\"tooltip\" data-placement=\"${position}\" title=\"" . $attributes[self::TEXT_ATTRIBUTE] . "\">" . DOKU_LF;
171                    };
172
173                    break;
174
175                case DOKU_LEXER_EXIT:
176                    if (isset($data[PluginUtility::ATTRIBUTES][self::TEXT_ATTRIBUTE])) {
177
178                        $text = $data[PluginUtility::ATTRIBUTES][self::TEXT_ATTRIBUTE];
179                        if (!empty($text)) {
180                            $renderer->doc .= "</span>";
181                            self::addToolTipSnippetIfNeeded();
182                        }
183
184                    }
185                    break;
186
187
188            }
189            return true;
190        }
191
192        // unsupported $mode
193        return false;
194    }
195
196
197}
198
199