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