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