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