##// END OF EJS Templates
tooltip updates, added display layout managment inspired by jQuerys tipsy.
marcink -
r292:d7aeae23 default
parent child Browse files
Show More
@@ -1,271 +1,295 b''
1 1 """Helper functions
2 2
3 3 Consists of functions to typically be used within templates, but also
4 4 available to Controllers. This module is available to both as 'h'.
5 5 """
6 6 from pygments.formatters import HtmlFormatter
7 7 from pygments import highlight as code_highlight
8 8 from pylons import url, app_globals as g
9 9 from pylons.i18n.translation import _, ungettext
10 10 from vcs.utils.annotate import annotate_highlight
11 11 from webhelpers.html import literal, HTML, escape
12 12 from webhelpers.html.tools import *
13 13 from webhelpers.html.builder import make_tag
14 14 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
15 15 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
16 16 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
17 17 password, textarea, title, ul, xml_declaration, radio
18 18 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
19 19 mail_to, strip_links, strip_tags, tag_re
20 20 from webhelpers.number import format_byte_size, format_bit_size
21 21 from webhelpers.pylonslib import Flash as _Flash
22 22 from webhelpers.pylonslib.secure_form import secure_form
23 23 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
24 24 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
25 25 replace_whitespace, urlify, truncate, wrap_paragraphs
26 26
27 27
28 28 #Custom helpers here :)
29 29 class _Link(object):
30 30 '''
31 31 Make a url based on label and url with help of url_for
32 32 @param label:name of link if not defined url is used
33 33 @param url: the url for link
34 34 '''
35 35
36 36 def __call__(self, label='', *url_, **urlargs):
37 37 if label is None or '':
38 38 label = url
39 39 link_fn = link_to(label, url(*url_, **urlargs))
40 40 return link_fn
41 41
42 42 link = _Link()
43 43
44 44 class _GetError(object):
45 45
46 46 def __call__(self, field_name, form_errors):
47 47 tmpl = """<span class="error_msg">%s</span>"""
48 48 if form_errors and form_errors.has_key(field_name):
49 49 return literal(tmpl % form_errors.get(field_name))
50 50
51 51 get_error = _GetError()
52 52
53 53 def recursive_replace(str, replace=' '):
54 54 """
55 55 Recursive replace of given sign to just one instance
56 56 @param str: given string
57 57 @param replace:char to find and replace multiple instances
58 58
59 59 Examples::
60 60 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
61 61 'Mighty-Mighty-Bo-sstones'
62 62 """
63 63
64 64 if str.find(replace * 2) == -1:
65 65 return str
66 66 else:
67 67 str = str.replace(replace * 2, replace)
68 68 return recursive_replace(str, replace)
69 69
70 70 class _ToolTip(object):
71 71
72 72 def __call__(self, tooltip_title, trim_at=50):
73 73 """
74 74 Special function just to wrap our text into nice formatted autowrapped
75 75 text
76 76 @param tooltip_title:
77 77 """
78 78
79 79 return literal(wrap_paragraphs(tooltip_title, trim_at)\
80 80 .replace('\n', '<br/>'))
81 81
82 82 def activate(self):
83 83 """
84 84 Adds tooltip mechanism to the given Html all tooltips have to have
85 85 set class tooltip and set attribute tooltip_title.
86 86 Then a tooltip will be generated based on that
87 87 All with yui js tooltip
88 88 """
89 89
90 90 js = '''
91 91 YAHOO.util.Event.onDOMReady(function(){
92 92 function toolTipsId(){
93 93 var ids = [];
94 94 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
95 95
96 96 for (var i = 0; i < tts.length; i++) {
97 97 //if element doesn not have and id autgenerate one for tooltip
98 98
99 99 if (!tts[i].id){
100 100 tts[i].id='tt'+i*100;
101 101 }
102 102 ids.push(tts[i].id);
103 103 }
104 104 return ids
105 105 };
106 106 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
107 107 context: toolTipsId(),
108 108 monitorresize:false,
109 109 xyoffset :[0,0],
110 110 autodismissdelay:300000,
111 111 hidedelay:5,
112 112 showdelay:20,
113 113 });
114 114
115 115 //Mouse Over event disabled for new repositories since they dont
116 116 //have last commit message
117 117 myToolTips.contextMouseOverEvent.subscribe(
118 118 function(type, args) {
119 119 var context = args[0];
120 120 var txt = context.getAttribute('tooltip_title');
121 if(txt){
122 this.cfg.config.x.value = 0;
123 this.cfg.config.y.value = 0;
124
121 if(txt){
125 122 return true;
126 123 }
127 124 else{
128 125 return false;
129 126 }
130 127 });
131 128
132 129
133 130 // Set the text for the tooltip just before we display it. Lazy method
134 131 myToolTips.contextTriggerEvent.subscribe(
135 132 function(type, args) {
133
134
136 135 var context = args[0];
136
137 137 var txt = context.getAttribute('tooltip_title');
138 138 this.cfg.setProperty("text", txt);
139 //autocenter
140 var w = this.element.clientWidth;
141 var h = this.element.clientHeight;
142 var cur_x = this.pageX - (w / 2);
143 var cur_y = this.pageY - h - 10;
139
140
141 // positioning of tooltip
142 var tt_w = this.element.clientWidth;
143 var tt_h = this.element.clientHeight;
144
145 var context_w = context.offsetWidth;
146 var context_h = context.offsetHeight;
147
148 var pos_x = YAHOO.util.Dom.getX(context);
149 var pos_y = YAHOO.util.Dom.getY(context);
144 150
145 this.cfg.setProperty("xy",[cur_x,cur_y]);
151 var display_strategy = 'top';
152 var xy_pos= [0,0]
153 switch (display_strategy){
154
155 case 'top':
156 var cur_x = (pos_x+context_w/2)-(tt_w/2);
157 var cur_y = pos_y-tt_h-4;
158 xy_pos = [cur_x,cur_y];
159 break;
160 case 'bottom':
161 var cur_x = (pos_x+context_w/2)-(tt_w/2);
162 var cur_y = pos_y+context_h+4;
163 xy_pos = [cur_x,cur_y];
164 break;
165 case 'left':
166 var cur_x = (pos_x-tt_w-4);
167 var cur_y = pos_y-((tt_h/2)-context_h/2);
168 xy_pos = [cur_x,cur_y];
169 break;
170 case 'right':
171 var cur_x = (pos_x+context_w+4);
172 var cur_y = pos_y-((tt_h/2)-context_h/2);
173 xy_pos = [cur_x,cur_y];
174 break;
175
176 }
177
178 this.cfg.setProperty("xy",xy_pos);
146 179
147 180 });
181
148 182 //Mouse out
149 183 myToolTips.contextMouseOutEvent.subscribe(
150 184 function(type, args) {
151 185 var context = args[0];
152 186
153 //console.log(this.cfg.config.x.value);
154 //console.log(this.cfg.config.y.value);
155 //console.log(this.cfg.config.xy.value);
156 //console.log(this.cfg.config);
157 //this.cfg.config.xy = [0,0];
158 //this.cfg.config.xyoffset = [0,0];
159
160
161
162 187 });
163
164 188 });
165 189 '''
166 190 return literal(js)
167 191
168 192 tooltip = _ToolTip()
169 193
170 194 class _FilesBreadCrumbs(object):
171 195
172 196 def __call__(self, repo_name, rev, paths):
173 197 url_l = [link_to(repo_name, url('files_home',
174 198 repo_name=repo_name,
175 199 revision=rev, f_path=''))]
176 200 paths_l = paths.split('/')
177 201
178 202 for cnt, p in enumerate(paths_l, 1):
179 203 if p != '':
180 204 url_l.append(link_to(p, url('files_home',
181 205 repo_name=repo_name,
182 206 revision=rev,
183 207 f_path='/'.join(paths_l[:cnt]))))
184 208
185 209 return literal(' / '.join(url_l))
186 210
187 211 files_breadcrumbs = _FilesBreadCrumbs()
188 212
189 213 def pygmentize(filenode, **kwargs):
190 214 """
191 215 pygmentize function using pygments
192 216 @param filenode:
193 217 """
194 218 return literal(code_highlight(filenode.content, filenode.lexer, HtmlFormatter(**kwargs)))
195 219
196 220 def pygmentize_annotation(filenode, **kwargs):
197 221 """
198 222 pygmentize function for annotation
199 223 @param filenode:
200 224 """
201 225
202 226 color_dict = g.changeset_annotation_colors
203 227 def gen_color():
204 228 import random
205 229 return [str(random.randrange(10, 235)) for _ in xrange(3)]
206 230 def get_color_string(cs):
207 231 if color_dict.has_key(cs):
208 232 col = color_dict[cs]
209 233 else:
210 234 color_dict[cs] = gen_color()
211 235 col = color_dict[cs]
212 236 return "color: rgb(%s) ! important;" % (', '.join(col))
213 237
214 238 def url_func(changeset):
215 239 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b> %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
216 240
217 241 tooltip_html = tooltip_html % (changeset.author,
218 242 changeset.date,
219 243 tooltip(changeset.message))
220 244 lnk_format = 'r%s:%s' % (changeset.revision,
221 245 changeset.raw_id)
222 246 uri = link_to(
223 247 lnk_format,
224 248 url('changeset_home', repo_name='test',
225 249 revision=changeset.raw_id),
226 250 style=get_color_string(changeset.raw_id),
227 251 class_='tooltip',
228 252 tooltip_title=tooltip_html
229 253 )
230 254
231 255 uri += '\n'
232 256 return uri
233 257 return literal(annotate_highlight(filenode, url_func, **kwargs))
234 258
235 259 def repo_name_slug(value):
236 260 """
237 261 Return slug of name of repository
238 262 """
239 263 slug = urlify(value)
240 264 for c in """=[]\;'"<>,/~!@#$%^&*()+{}|:""":
241 265 slug = slug.replace(c, '-')
242 266 slug = recursive_replace(slug, '-')
243 267 return slug
244 268
245 269 flash = _Flash()
246 270
247 271
248 272 #===============================================================================
249 273 # MERCURIAL FILTERS available via h.
250 274 #===============================================================================
251 275
252 276
253 277 from mercurial import util
254 278 from mercurial.templatefilters import age as _age, person as _person
255 279
256 280 age = lambda x:_age(x)
257 281 capitalize = lambda x: x.capitalize()
258 282 date = lambda x: util.datestr(x)
259 283 email = util.email
260 284 person = lambda x: _person(x)
261 285 hgdate = lambda x: "%d %d" % x
262 286 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
263 287 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
264 288 localdate = lambda x: (x[0], util.makedate()[1])
265 289 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
266 290 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
267 291 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
268 292
269 293
270 294
271 295
General Comments 0
You need to be logged in to leave comments. Login now