16bfd3f23SEli Fenton<?php 26bfd3f23SEli Fentonif(!defined('DOKU_INC')) die(); 36bfd3f23SEli Fenton 46bfd3f23SEli Fenton/** 56bfd3f23SEli Fenton * Auto-Tooltip DokuWiki plugin 66bfd3f23SEli Fenton * 76bfd3f23SEli Fenton * @license MIT 86bfd3f23SEli Fenton * @author Eli Fenton 96bfd3f23SEli Fenton */ 106bfd3f23SEli Fentonclass helper_plugin_autotooltip extends DokuWiki_Admin_Plugin { 116bfd3f23SEli Fenton private $localRenderer; 126bfd3f23SEli Fenton 136bfd3f23SEli Fenton public function __construct() { 146bfd3f23SEli Fenton $this->localRenderer = new Doku_Renderer_xhtml; 156bfd3f23SEli Fenton } 166bfd3f23SEli Fenton 176bfd3f23SEli Fenton 186bfd3f23SEli Fenton /** 196bfd3f23SEli Fenton * Return a simple tooltip. 206bfd3f23SEli Fenton * 2107c401fcSEli Fenton * @param string $content - The on-page content. May contain newlines. 22948a1374SEli Fenton * @param string $tooltip - The tooltip content. Newlines will be rendered as line breaks. 23948a1374SEli Fenton * @param string $title - The title inside the tooltip. 24948a1374SEli Fenton * @param string $preTitle - Text to display before the title. Newlines will be rendered as line breaks. 256bfd3f23SEli Fenton * @param string $classes - CSS classes to add to this tooltip. 26969d3afcSEli Fenton * @param string $textStyle - CSS styles for the linked content 276bfd3f23SEli Fenton * @return string 286bfd3f23SEli Fenton */ 29e4338dabSEli Fenton function forText($content, $tooltip, $title='', $preTitle = '', $classes = '', $textStyle = '') { 306bfd3f23SEli Fenton if (!$classes) { 31*be213c94SEli Fenton $classes = $this->getConf('style'); 32*be213c94SEli Fenton } 33*be213c94SEli Fenton if (!$classes) { 34*be213c94SEli Fenton $classes = 'default'; 35*be213c94SEli Fenton } 36*be213c94SEli Fenton 37*be213c94SEli Fenton // Sanitize 38*be213c94SEli Fenton $classes = htmlspecialchars($classes); 39*be213c94SEli Fenton // Add the plugin prefix to all classes. 40*be213c94SEli Fenton $classes = preg_replace('/(\w+)/', 'plugin-autotooltip__$1', $classes); 41*be213c94SEli Fenton 42*be213c94SEli Fenton $partCount = (empty($title) ? 0 : 1) + (empty($preTitle) ? 0 : 1) + (empty($tooltip) ? 0 : 1); 43*be213c94SEli Fenton if ($partCount > 1 || strchr($tooltip, "\n") !== FALSE || strlen($tooltip) > 40) { 44*be213c94SEli Fenton $classes .= ' plugin-autotooltip_big'; 456bfd3f23SEli Fenton } 466bfd3f23SEli Fenton 47969d3afcSEli Fenton $textClass = ''; 48969d3afcSEli Fenton if (empty($textStyle)) { 49969d3afcSEli Fenton $textClass = 'plugin-autotooltip_linked'; 50969d3afcSEli Fenton if (strstr($content, '<a ') === FALSE) { 51969d3afcSEli Fenton $textClass .= ' plugin-autotooltip__simple'; 52969d3afcSEli Fenton } 53969d3afcSEli Fenton } 546bfd3f23SEli Fenton 55e4338dabSEli Fenton $contentParts = []; 56e4338dabSEli Fenton if (!empty($preTitle)) { 57948a1374SEli Fenton $contentParts[] = $this->_formatTT($preTitle); 58e4338dabSEli Fenton } 59e4338dabSEli Fenton if (!empty($title)) { 60e4338dabSEli Fenton $contentParts[] = '<span class="plugin-autotooltip-title">' . $title . '</span>'; 61e4338dabSEli Fenton } 62e4338dabSEli Fenton if (!empty($tooltip)) { 63948a1374SEli Fenton $contentParts[] = $this->_formatTT($tooltip); 64e4338dabSEli Fenton } 65e4338dabSEli Fenton 66969d3afcSEli Fenton return '<span class="' . $textClass . '" style="' . $textStyle . '" onmouseover="autotooltip.show(this)" onmouseout="autotooltip.hide()">' . 676bfd3f23SEli Fenton $content . 6807c401fcSEli Fenton '<span class="plugin-autotooltip-hidden-classes">' . $classes . '</span>' . 69e4338dabSEli Fenton '<span class="plugin-autotooltip-hidden-tip">' . 70e4338dabSEli Fenton implode('<br><br>', $contentParts) . 71e4338dabSEli Fenton '</span>' . 7207c401fcSEli Fenton '</span>'; 736bfd3f23SEli Fenton } 746bfd3f23SEli Fenton 756bfd3f23SEli Fenton 766bfd3f23SEli Fenton /** 776bfd3f23SEli Fenton * Render a tooltip, with the title and abstract of a page. 786bfd3f23SEli Fenton * 796bfd3f23SEli Fenton * @param string $id - A page id. 80948a1374SEli Fenton * @param string $content - The on-page content. Newlines will be rendered as line breaks. Omit to use the page's title. 81948a1374SEli Fenton * @param string $preTitle - Text to display before the title in the tooltip. Newlines will be rendered as line breaks. 826bfd3f23SEli Fenton * @param string $classes - CSS classes to add to this tooltip. 83969d3afcSEli Fenton * @param string $linkStyle - Style attribute for the link. 846bfd3f23SEli Fenton * @return string 856bfd3f23SEli Fenton */ 86e4338dabSEli Fenton function forWikilink($id, $content = null, $preTitle = '', $classes = '', $linkStyle = '') { 876bfd3f23SEli Fenton $title = p_get_metadata($id, 'title'); 886bfd3f23SEli Fenton $abstract = p_get_metadata($id, 'description abstract'); 89d852dc10SEli Fenton 906bfd3f23SEli Fenton // By default, the abstract starts with the title. Remove it so it's not displayed twice, but still fetch 916bfd3f23SEli Fenton // both pieces of metadata, in case another plugin rewrote the abstract. 92d852dc10SEli Fenton $abstract = preg_replace('/^' . $this->_pregEscape($title) . '(\r?\n)+/', '', $abstract); 936bfd3f23SEli Fenton 94812ebc9aSEli Fenton $link = $this->localRenderer->internallink($id, $content ?: $title, null, true); 956bfd3f23SEli Fenton 96969d3afcSEli Fenton if (!empty($linkStyle)) { 97969d3afcSEli Fenton $link = preg_replace('/<a /', '<a style="' . $linkStyle . '" ', $link); 98969d3afcSEli Fenton } 99969d3afcSEli Fenton 1006bfd3f23SEli Fenton if (page_exists($id)) { 1016bfd3f23SEli Fenton // Remove the title attribute, since we have a better tooltip. 1026bfd3f23SEli Fenton $link = preg_replace('/title="[^"]*"/', '', $link); 103*be213c94SEli Fenton return $this->forText($link, $abstract, $title, $preTitle, $classes); 1046bfd3f23SEli Fenton } 1056bfd3f23SEli Fenton else { 1066bfd3f23SEli Fenton return $link; 1076bfd3f23SEli Fenton } 1086bfd3f23SEli Fenton } 1096bfd3f23SEli Fenton 1106bfd3f23SEli Fenton 1116bfd3f23SEli Fenton /** 1126bfd3f23SEli Fenton * Format tooltip text. 1136bfd3f23SEli Fenton * 1146bfd3f23SEli Fenton * @param string $tt - Tooltip text. 1156bfd3f23SEli Fenton * @return string 1166bfd3f23SEli Fenton */ 1176bfd3f23SEli Fenton private function _formatTT($tt) { 118948a1374SEli Fenton // Convert double-newlines into vertical space. 119948a1374SEli Fenton $tt = preg_replace('/(\r?\n){2,}/', '<br><br>', $tt); 120948a1374SEli Fenton // Single newlines get collapsed, just like in HTML. 121948a1374SEli Fenton return preg_replace('/(\r?\n)/', ' ', $tt); 1226bfd3f23SEli Fenton } 123d852dc10SEli Fenton 124d852dc10SEli Fenton 125d852dc10SEli Fenton /** 126d852dc10SEli Fenton * Escape a string for inclusion in a regular expression, assuming forward slash is used as the delimiter. 127d852dc10SEli Fenton * 128d852dc10SEli Fenton * @param string $r - The regex string, without delimiters. 129d852dc10SEli Fenton * @return string 130d852dc10SEli Fenton */ 131d852dc10SEli Fenton private function _pregEscape($r) { 132d852dc10SEli Fenton return preg_replace('/\//', '\\/', preg_quote($r)); 133d852dc10SEli Fenton } 1346bfd3f23SEli Fenton} 135