xref: /plugin/autotooltip/helper.php (revision 948a13744b469affa232753d7bac4703e5ead02b)
1<?php
2if(!defined('DOKU_INC')) die();
3
4/**
5 * Auto-Tooltip DokuWiki plugin
6 *
7 * @license    MIT
8 * @author     Eli Fenton
9 */
10class helper_plugin_autotooltip extends DokuWiki_Admin_Plugin {
11	private $localRenderer;
12
13	public function __construct() {
14		$this->localRenderer = new Doku_Renderer_xhtml;
15	}
16
17
18	/**
19	 * Return a simple tooltip.
20	 *
21	 * @param string $content - The on-page content. May contain newlines.
22	 * @param string $tooltip - The tooltip content. Newlines will be rendered as line breaks.
23	 * @param string $title - The title inside the tooltip.
24	 * @param string $preTitle - Text to display before the title. Newlines will be rendered as line breaks.
25	 * @param string $classes - CSS classes to add to this tooltip.
26	 * @param string $textStyle - CSS styles for the linked content
27	 * @return string
28	 */
29	function forText($content, $tooltip, $title='', $preTitle = '', $classes = '', $textStyle = '') {
30		if (!$classes) {
31			$classes = 'plugin-autotooltip__default';
32		}
33
34		$textClass = '';
35		if (empty($textStyle)) {
36			$textClass = 'plugin-autotooltip_linked';
37			if (strstr($content, '<a ') === FALSE) {
38				$textClass .= ' plugin-autotooltip__simple';
39			}
40		}
41
42		$contentParts = [];
43		if (!empty($preTitle)) {
44			$contentParts[] = $this->_formatTT($preTitle);
45		}
46		if (!empty($title)) {
47			$contentParts[] = '<span class="plugin-autotooltip-title">' . $title . '</span>';
48		}
49		if (!empty($tooltip)) {
50			$contentParts[] = $this->_formatTT($tooltip);
51		}
52
53		return '<span class="' . $textClass . '" style="' . $textStyle . '" onmouseover="autotooltip.show(this)" onmouseout="autotooltip.hide()">' .
54			$content .
55			'<span class="plugin-autotooltip-hidden-classes">' . $classes . '</span>' .
56			'<span class="plugin-autotooltip-hidden-tip">' .
57			implode('<br><br>', $contentParts) .
58			'</span>' .
59		'</span>';
60	}
61
62
63	/**
64	 * Render a tooltip, with the title and abstract of a page.
65	 *
66	 * @param string $id - A page id.
67	 * @param string $content - The on-page content. Newlines will be rendered as line breaks. Omit to use the page's title.
68	 * @param string $preTitle - Text to display before the title in the tooltip. Newlines will be rendered as line breaks.
69	 * @param string $classes - CSS classes to add to this tooltip.
70	 * @param string $linkStyle - Style attribute for the link.
71	 * @return string
72	 */
73	function forWikilink($id, $content = null, $preTitle = '', $classes = '', $linkStyle = '') {
74		if (!$classes) {
75			$classes = 'plugin-autotooltip__default';
76		}
77
78		$title = p_get_metadata($id, 'title');
79		$abstract = p_get_metadata($id, 'description abstract');
80
81		// By default, the abstract starts with the title. Remove it so it's not displayed twice, but still fetch
82		// both pieces of metadata, in case another plugin rewrote the abstract.
83		$abstract = preg_replace('/^' . $this->_pregEscape($title) . '(\r?\n)+/', '', $abstract);
84
85		$link = $this->localRenderer->internallink($id, $content ?: $title, null, true);
86
87		if (!empty($linkStyle)) {
88			$link = preg_replace('/<a /', '<a style="' . $linkStyle . '" ', $link);
89		}
90
91		if (page_exists($id)) {
92			// Remove the title attribute, since we have a better tooltip.
93			$link = preg_replace('/title="[^"]*"/', '', $link);
94			return $this->forText($link, $abstract, $title, $preTitle, "plugin-autotooltip_big $classes");
95		}
96		else {
97			return $link;
98		}
99	}
100
101
102	/**
103	 * Format tooltip text.
104	 *
105	 * @param string $tt - Tooltip text.
106	 * @return string
107	 */
108	private function _formatTT($tt) {
109		// Convert double-newlines into vertical space.
110		$tt = preg_replace('/(\r?\n){2,}/', '<br><br>', $tt);
111		// Single newlines get collapsed, just like in HTML.
112		return preg_replace('/(\r?\n)/', ' ', $tt);
113	}
114
115
116	/**
117	 * Escape a string for inclusion in a regular expression, assuming forward slash is used as the delimiter.
118	 *
119	 * @param string $r - The regex string, without delimiters.
120	 * @return string
121	 */
122	private function _pregEscape($r) {
123		return preg_replace('/\//', '\\/', preg_quote($r));
124	}
125}
126