xref: /template/strap/syntax/tooltip.php (revision 32b85071e019dd3646a67c17fac4051338e495eb)
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 PluginUtility::handleAndReturnUnmatchedData(self::TAG,$match,$handler);
122
123            case DOKU_LEXER_EXIT :
124
125                $tag = new Tag(self::TAG, array(), $state, $handler);
126
127                return array(
128                    PluginUtility::STATE => $state,
129                    PluginUtility::ATTRIBUTES => $tag->getOpeningTag()->getAttributes()
130                );
131
132
133        }
134        return array();
135
136    }
137
138    /**
139     * Render the output
140     * @param string $format
141     * @param Doku_Renderer $renderer
142     * @param array $data - what the function handle() return'ed
143     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
144     * @see DokuWiki_Syntax_Plugin::render()
145     *
146     *
147     */
148    function render($format, Doku_Renderer $renderer, $data)
149    {
150        if ($format == 'xhtml') {
151
152            /** @var Doku_Renderer_xhtml $renderer */
153            $state = $data[PluginUtility::STATE];
154            switch ($state) {
155
156                case DOKU_LEXER_UNMATCHED:
157                    $renderer->doc .= PluginUtility::renderUnmatched($data);
158                    break;
159                case DOKU_LEXER_ENTER :
160                    $attributes = $data[PluginUtility::ATTRIBUTES];
161
162                    if (isset($attributes[self::TEXT_ATTRIBUTE])) {
163                        $position = "top";
164                        if (isset($attributes[self::POSITION_ATTRIBUTE])) {
165                            $position = $attributes[self::POSITION_ATTRIBUTE];
166                        }
167                        $renderer->doc .= "<span class=\"d-inline-block\" tabindex=\"0\" data-toggle=\"tooltip\" data-placement=\"${position}\" title=\"" . $attributes[self::TEXT_ATTRIBUTE] . "\">" . DOKU_LF;
168                    };
169
170                    break;
171
172                case DOKU_LEXER_EXIT:
173                    if (isset($data[PluginUtility::ATTRIBUTES][self::TEXT_ATTRIBUTE])) {
174
175                        $text = $data[PluginUtility::ATTRIBUTES][self::TEXT_ATTRIBUTE];
176                        if (!empty($text)) {
177                            $renderer->doc .= "</span>";
178                            self::addToolTipSnippetIfNeeded();
179                        }
180
181                    }
182                    break;
183
184
185            }
186            return true;
187        }
188
189        // unsupported $mode
190        return false;
191    }
192
193
194}
195
196