1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8function wikiplugin_mouseover_info() 9{ 10 global $prefs; 11 include_once('lib/prefs/jquery.php'); 12 $jqprefs = prefs_jquery_list(); 13 $jqfx = []; 14 foreach ($jqprefs['jquery_effect']['options'] as $k => $v) { 15 $jqfx[] = ['text' => $v, 'value' => $k]; 16 } 17 18 19 return [ 20 'name' => tra('Mouseover'), 21 'documentation' => 'PluginMouseover', 22 'description' => tra('Display hidden content by mousing over text'), 23 'prefs' => [ 'wikiplugin_mouseover' ], 24 'body' => tra('Hidden content, unless the label parameter is undefined, in which case this is the label.'), 25 'iconname' => 'comment', 26 'introduced' => 3, 27 'tags' => [ 'basic' ], 28 'params' => [ 29 'label' => [ 30 'required' => true, 31 'name' => tra('Label'), 32 'description' => tra('Text displayed on the page. The body is the hidden content.'), 33 'since' => '3.0', 34 'filter' => 'text', 35 'default' => '', 36 ], 37 'url' => [ 38 'required' => false, 39 'name' => tra('URL'), 40 'description' => tra('Destination link when mouseover text is clicked. Use http:// for external links'), 41 'since' => '3.0', 42 'filter' => 'url', 43 'default' => 'javascript:void(0)', 44 ], 45 'text' => [ 46 'required' => false, 47 'name' => tra('Text'), 48 'description' => tra('DEPRECATED') . ' ' . tra('Hidden content. The body contains the label.'), 49 'since' => '3.0', 50 'filter' => 'text', 51 'default' => '', 52 'advanced' => true, 53 ], 54 'width' => [ 55 'required' => false, 56 'name' => tra('Width'), 57 'description' => tr('Mouseover box width. Default: %0400px%1', '<code>', '</code>'), 58 'since' => '3.0', 59 'filter' => 'digits', 60 'default' => 400, 61 'advanced' => true, 62 ], 63 'height' => [ 64 'required' => false, 65 'name' => tra('Height'), 66 'description' => tr('Mouseover box height. Default: %0200px%1', '<code>', '</code>'), 67 'since' => '3.0', 68 'filter' => 'digits', 69 'default' => 200, 70 'advanced' => true, 71 ], 72 'offsetx' => [ 73 'required' => false, 74 'name' => tra('Offset X'), 75 'description' => tr('Shifts the overlay to the right by the specified number of pixels relative to 76 the cursor. Default: %05%1', '<code>', '</code>'), 77 'since' => '3.0', 78 'filter' => 'int', 79 'default' => 5, 80 'advanced' => true, 81 ], 82 'offsety' => [ 83 'required' => false, 84 'name' => tra('Offset Y'), 85 'description' => tr('Shifts the overlay lower by the specified number of pixels relative to the 86 cursor. Default: %00%1', '<code>', '</code>'), 87 'since' => '3.0', 88 'filter' => 'int', 89 'default' => 24, 90 'advanced' => true, 91 ], 92 'parse' => [ 93 'required' => false, 94 'name' => tra('Parse Body'), 95 'description' => tra('Parse the body of the plugin as wiki content (parsed by default)'), 96 'since' => '3.0', 97 'filter' => 'alpha', 98 'advanced' => true, 99 'default' => 'y', 100 'options' => [ 101 ['text' => '', 'value' => ''], 102 ['text' => tra('Yes'), 'value' => 'y'], 103 ['text' => tra('No'), 'value' => 'n'] 104 ] 105 ], 106 'parselabel' => [ 107 'required' => false, 108 'name' => tra('Parse Label'), 109 'description' => tra('Parse the label as wiki content (parsed by default)'), 110 'since' => '5.0', 111 'filter' => 'alpha', 112 'default' => 'y', 113 'advanced' => true, 114 'options' => [ 115 ['text' => '', 'value' => ''], 116 ['text' => tra('Yes'), 'value' => 'y'], 117 ['text' => tra('No'), 'value' => 'n'] 118 ] 119 ], 120 'class' => [ 121 'required' => false, 122 'name' => tra('CSS Class'), 123 'description' => tra('CSS class to apply'), 124 'since' => '4.0', 125 'filter' => 'text', 126 'default' => 'plugin-mouseover', 127 'advanced' => true, 128 ], 129 'bgcolor' => [ 130 'required' => false, 131 'name' => tra('Background Color'), 132 'description' => tra('Background color to apply to the popup'), 133 'since' => '3.0', 134 'filter' => 'text', 135 'default' => '', 136 'advanced' => true, 137 ], 138 'textcolor' => [ 139 'required' => false, 140 'name' => tra('Text Color'), 141 'description' => tra('Color to apply to the text in the popup'), 142 'since' => '3.0', 143 'filter' => 'text', 144 'default' => '', 145 'advanced' => true, 146 ], 147 'sticky' => [ 148 'required' => false, 149 'name' => tra('Sticky'), 150 'description' => tra('When enabled, popup stays visible until it is clicked.'), 151 'since' => '3.0', 152 'filter' => 'alpha', 153 'default' => '', 154 'options' => [ 155 ['text' => '', 'value' => ''], 156 ['text' => tra('Yes'), 'value' => 'y'], 157 ['text' => tra('No'), 'value' => 'n'] 158 ], 159 'advanced' => true, 160 ], 161 'padding' => [ 162 'required' => false, 163 'name' => tra('Padding'), 164 'description' => tra('Padding size in pixels'), 165 'since' => '3.0', 166 'filter' => 'digits', 167 'default' => '', 168 'advanced' => true, 169 ], 170 'effect' => [ 171 'required' => false, 172 'name' => tra('Effect'), 173 'options' => $jqfx, 174 'description' => tra('Set the type of show/hide animation that will be used'), 175 'since' => '4.0', 176 'filter' => 'text', 177 'advanced' => true, 178 ], 179 'speed' => [ 180 'required' => false, 181 'name' => tra('Effect Speed'), 182 'options' => [ 183 ['text' => tra('Normal'), 'value' => ''], 184 ['text' => tra('Fast'), 'value' => 'fast'], 185 ['text' => tra('Slow'), 'value' => 'slow'], 186 ], 187 'description' => tra('Set the speed of the animation.'), 188 'since' => '4.0', 189 'filter' => 'alpha', 190 'default' => '', 191 'advanced' => true, 192 ], 193 'closeDelay' => [ 194 'required' => false, 195 'name' => tra('Close Delay'), 196 'description' => tra('Number of seconds before popup closes'), 197 'since' => '5.0', 198 'filter' => 'digits', 199 'default' => 0, 200 'advanced' => true, 201 ], 202 'tag' => [ 203 'required' => false, 204 'name' => tra('Tag'), 205 'description' => tr('HTML tag to use for the label. Default %0a%1', '<code>', '</code>'), 206 'since' => '9.2', 207 'filter' => 'word', 208 'default' => 'a', 209 'advanced' => true, 210 ], 211 ], 212 ]; 213} 214 215function wikiplugin_mouseover($data, $params) 216{ 217 $default = ['parse' => 'y', 'parselabel' => 'y']; 218 $params = array_merge($default, $params); 219 220 $width = isset($params['width']) ? (int) $params['width'] : 400; 221 $height = isset($params['height']) ? (int) $params['height'] : 200; 222 $offsetx = isset($params['offsetx']) ? (int) $params['offsetx'] : 5; 223 $offsety = isset($params['offsety']) ? (int) $params['offsety'] : 24; 224 $parse = ! isset($params['parse']) || (strcasecmp($params['parse'], 'n') != 0); 225 $sticky = isset($params['sticky']) && $params['sticky'] == 'y'; 226 $padding = isset($params['padding']) ? 'padding: ' . $params['padding'] . 'px;' : ''; 227 $effect = ! isset($params['effect']) || $params['effect'] == 'Default' ? '' : strtolower($params['effect']); 228 $speed = ! isset($params['speed']) ? 'normal' : strtolower($params['speed']); 229 $closeDelay = isset($params['closeDelay']) ? (int) $params['closeDelay'] : 0; 230 $tag = ! empty($params['tag']) ? $params['tag'] : 'a'; 231 232 if (empty($params['label']) && empty($params['text'])) { 233 $label = tra('No label specified'); 234 } else { 235 $label = ! empty($params['label']) ? $params['label'] : $data; 236 $text = ! empty($params['text']) ? $params['text'] : $data; 237 } 238 239 $url = ''; 240 if (isset($params['url'])) { 241 $url = $params['url']; 242 $url = htmlentities($url, ENT_QUOTES, 'UTF-8'); 243 } 244 245 $text = trim($text); 246 247 if (empty($text)) { 248 if ($params['parselabel'] == 'y') { 249 return $label; 250 } else { 251 return "~np~$label~/np~"; 252 } 253 } 254 255 if ($parse) { 256 $options = ['is_html' => 0]; 257 if (containsStringHTML($text)) { 258 $options = ['is_html' => 1]; 259 } 260 $text = TikiLib::lib('parser')->parse_data($text, $options); 261 } 262 if ($params['parselabel'] == 'y') { 263 $label = "~/np~$label~np~"; 264 } 265 266 static $lastval = 0; 267 $id = "mo" . ++$lastval; 268 269 $headerlib = TikiLib::lib('header'); 270 $headerlib->add_css('.plugin-mouseover-anchor:not([href]) { border-bottom: 1px dotted; color: inherit; cursor: help; text-decoration: none; }'); 271 272 if ($closeDelay && $sticky) { 273 $closeDelayStr = "setTimeout(function() {hideJQ('#$id', '$effect', '$speed')}, " . ($closeDelay * 1000) . ");"; 274 } else { 275 $closeDelayStr = ''; 276 } 277 278 $js = "\$('#$id-link').mouseover(function(event) { 279 var pos = $(this).position(); 280 $(this).closest('td').css('position', 'relative'); 281 \$('#$id').css('position', 'absolute').css('left', pos.left + $offsetx + 'px').css('top', pos.top + $offsety + 'px'); 282 showJQ('#$id', '$effect', '$speed'); $closeDelayStr }); 283"; 284 if ($sticky) { 285 $js .= "\$('#$id').click(function(event) { hideJQ('#$id', '$effect', '$speed'); }).css('cursor','pointer');\n"; 286 } else { 287 $js .= "\$('#$id-link').mouseout(function(event) { setTimeout(function() {hideJQ('#$id', '$effect', '$speed')}, " . ($closeDelay * 1000) . "); });"; 288 } 289 $headerlib->add_jq_onready($js); 290 291 $bgcolor = isset($params['bgcolor']) ? ("background-color: " . $params['bgcolor'] . ';') : ''; 292 $textcolor = isset($params['textcolor']) ? ("color:" . $params['textcolor'] . ';') : ''; 293 $class = ! isset($params['class']) ? 'class="plugin-mouseover"' : 'class="plugin-mouseover ' . $params['class'] . '"'; 294 $href = $url ? 'href="' . $url . '"' : ''; 295 296 $html = "~np~<$tag id=\"$id-link\" $href class=\"plugin-mouseover-anchor\">$label</$tag>" . 297 "<span id=\"$id\" $class style=\"width: {$width}px; " . (isset($params['height']) ? "height: {$height}px; " : "") . "{$bgcolor} {$textcolor} {$padding} \">$text</span>~/np~"; 298 299 return $html; 300} 301 302function containsStringHTML($str) 303{ 304 return preg_match('/<[^>]*>/', $str) == 1; 305} 306