##// END OF EJS Templates
mentions: markdown renderer now wraps username in hovercard logic allowing checking the mentioned user....
marcink -
r4221:654aa611 stable
parent child Browse files
Show More
@@ -26,6 +26,10 b' def includeme(config):'
26 26 pattern='/_hovercard/user/{user_id}')
27 27
28 28 config.add_route(
29 name='hovercard_username',
30 pattern='/_hovercard/username/{username}')
31
32 config.add_route(
29 33 name='hovercard_user_group',
30 34 pattern='/_hovercard/user_group/{user_group_id}')
31 35
@@ -65,6 +65,19 b' class HoverCardsView(BaseAppView):'
65 65
66 66 @LoginRequired()
67 67 @view_config(
68 route_name='hovercard_username', request_method='GET', xhr=True,
69 renderer='rhodecode:templates/hovercards/hovercard_user.mako')
70 def hovercard_username(self):
71 c = self.load_default_context()
72 username = self.request.matchdict['username']
73 c.user = User.get_by_username(username)
74 if not c.user:
75 raise HTTPNotFound()
76
77 return self._get_template_context(c)
78
79 @LoginRequired()
80 @view_config(
68 81 route_name='hovercard_user_group', request_method='GET', xhr=True,
69 82 renderer='rhodecode:templates/hovercards/hovercard_user_group.mako')
70 83 def hovercard_user_group(self):
@@ -66,11 +66,12 b' markdown_tags = ['
66 66 markdown_attrs = {
67 67 "*": ["class", "style", "align"],
68 68 "img": ["src", "alt", "title"],
69 "a": ["href", "alt", "title", "name"],
69 "a": ["href", "alt", "title", "name", "data-hovercard-alt", "data-hovercard-url"],
70 70 "abbr": ["title"],
71 71 "acronym": ["title"],
72 72 "pre": ["lang"],
73 "input": ["type", "disabled", "checked"]
73 "input": ["type", "disabled", "checked"],
74 "strong": ["title", "data-hovercard-alt", "data-hovercard-url"],
74 75 }
75 76
76 77 standard_styles = [
@@ -47,6 +47,14 b' log = logging.getLogger(__name__)'
47 47 # default renderer used to generate automated comments
48 48 DEFAULT_COMMENTS_RENDERER = 'rst'
49 49
50 try:
51 from lxml.html import fromstring
52 from lxml.html import tostring
53 except ImportError:
54 log.exception('Failed to import lxml')
55 fromstring = None
56 tostring = None
57
50 58
51 59 class CustomHTMLTranslator(writers.html4css1.HTMLTranslator):
52 60 """
@@ -81,11 +89,7 b' def relative_links(html_source, server_p'
81 89 if not html_source:
82 90 return html_source
83 91
84 try:
85 from lxml.html import fromstring
86 from lxml.html import tostring
87 except ImportError:
88 log.exception('Failed to import lxml')
92 if not fromstring and tostring:
89 93 return html_source
90 94
91 95 try:
@@ -210,6 +214,8 b' class MarkupRenderer(object):'
210 214 URL_PAT = re.compile(r'(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'
211 215 r'|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)')
212 216
217 MENTION_PAT = re.compile(MENTIONS_REGEX)
218
213 219 extensions = ['markdown.extensions.codehilite', 'markdown.extensions.extra',
214 220 'markdown.extensions.def_list', 'markdown.extensions.sane_lists']
215 221
@@ -348,6 +354,26 b' class MarkupRenderer(object):'
348 354 return cls.URL_PAT.sub(url_func, text)
349 355
350 356 @classmethod
357 def convert_mentions(cls, text, mode):
358 mention_pat = cls.MENTION_PAT
359
360 def wrapp(match_obj):
361 uname = match_obj.groups()[0]
362 hovercard_url = "pyroutes.url('hovercard_username', {'username': '%s'});" % uname
363
364 if mode == 'markdown':
365 tmpl = '<strong class="tooltip-hovercard" data-hovercard-alt="{uname}" data-hovercard-url="{hovercard_url}">@{uname}</strong>'
366 elif mode == 'rst':
367 tmpl = ' **@{uname}** '
368 else:
369 raise ValueError('mode must be rst or markdown')
370
371 return tmpl.format(**{'uname': uname,
372 'hovercard_url': hovercard_url})
373
374 return mention_pat.sub(wrapp, text).strip()
375
376 @classmethod
351 377 def plain(cls, source, universal_newline=True, leading_newline=True):
352 378 source = safe_unicode(source)
353 379 if universal_newline:
@@ -378,12 +404,7 b' class MarkupRenderer(object):'
378 404 cls.extensions, cls.output_format)
379 405
380 406 if mentions:
381 mention_pat = re.compile(MENTIONS_REGEX)
382
383 def wrapp(match_obj):
384 uname = match_obj.groups()[0]
385 return ' **@%(uname)s** ' % {'uname': uname}
386 mention_hl = mention_pat.sub(wrapp, source).strip()
407 mention_hl = cls.convert_mentions(source, mode='markdown')
387 408 # we extracted mentions render with this using Mentions false
388 409 return cls.markdown(mention_hl, safe=safe, flavored=flavored,
389 410 mentions=False)
@@ -409,12 +430,7 b' class MarkupRenderer(object):'
409 430 @classmethod
410 431 def rst(cls, source, safe=True, mentions=False, clean_html=False):
411 432 if mentions:
412 mention_pat = re.compile(MENTIONS_REGEX)
413
414 def wrapp(match_obj):
415 uname = match_obj.groups()[0]
416 return ' **@%(uname)s** ' % {'uname': uname}
417 mention_hl = mention_pat.sub(wrapp, source).strip()
433 mention_hl = cls.convert_mentions(source, mode='rst')
418 434 # we extracted mentions render with this using Mentions false
419 435 return cls.rst(mention_hl, safe=safe, mentions=False)
420 436
@@ -443,7 +459,7 b' class MarkupRenderer(object):'
443 459 except Exception:
444 460 log.exception('Error when rendering RST')
445 461 if safe:
446 log.debug('Fallbacking to render in plain mode')
462 log.debug('Fallback to render in plain mode')
447 463 return cls.plain(source)
448 464 else:
449 465 raise
@@ -87,6 +87,10 b' body {'
87 87 border-left: @border-thickness solid @border-default-color;
88 88 }
89 89
90 .cursor-pointer {
91 cursor: pointer;
92 }
93
90 94 input + .action-link, .action-link.first{
91 95 border-left: none;
92 96 }
@@ -31,6 +31,7 b' function registerRCRoutes() {'
31 31 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
32 32 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
33 33 pyroutes.register('hovercard_user', '/_hovercard/user/%(user_id)s', ['user_id']);
34 pyroutes.register('hovercard_username', '/_hovercard/username/%(username)s', ['username']);
34 35 pyroutes.register('hovercard_user_group', '/_hovercard/user_group/%(user_group_id)s', ['user_group_id']);
35 36 pyroutes.register('hovercard_pull_request', '/_hovercard/pull_request/%(pull_request_id)s', ['pull_request_id']);
36 37 pyroutes.register('hovercard_repo_commit', '/_hovercard/commit/%(repo_name)s/%(commit_id)s', ['repo_name', 'commit_id']);
@@ -299,6 +299,10 b' var tooltipActivate = function () {'
299 299 var altHovercard =$origin.data('hovercardAlt');
300 300
301 301 if (hovercardUrl !== undefined && hovercardUrl !== "") {
302 if (hovercardUrl.substr(0,12) === 'pyroutes.url'){
303 hovercardUrl = eval(hovercardUrl)
304 }
305
302 306 var loaded = loadHoverCard(hovercardUrl, altHovercard, function (data) {
303 307 instance.content(data);
304 308 })
General Comments 0
You need to be logged in to leave comments. Login now