Merge "Fix babel msgids to include tag attributes and entities" into stable/mitaka

This commit is contained in:
Jenkins 2016-06-02 18:08:42 +00:00 committed by Gerrit Code Review
commit f4b9e17315
3 changed files with 49 additions and 2 deletions

View File

@ -1,3 +1,4 @@
# -*- encoding: UTF-8 -*-
# Copyright 2015, Rackspace, US, Inc. # Copyright 2015, Rackspace, US, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -170,3 +171,20 @@ class ExtractAngularTestCase(test.TestCase):
self.assertEqual( self.assertEqual(
[(1, 'gettext', 'hello <b>beautiful <i>world</i></b> !', [])], [(1, 'gettext', 'hello <b>beautiful <i>world</i></b> !', [])],
messages) messages)
def test_nested_variations(self):
buf = StringIO(
'''
<p translate>To <a href="link">link</a> here</p>
<p translate>To <!-- a comment!! --> here</p>
<p translate>To trademark&reg; &#62; &#x3E; here</p>
'''
)
messages = list(extract_angular(buf, [], [], {}))
self.assertEqual(
[
(2, u'gettext', 'To <a href="link">link</a> here', []),
(3, u'gettext', 'To <!-- a comment!! --> here', []),
(4, u'gettext', u'To trademark® &#62; &#x3E; here', []),
],
messages)

View File

@ -1,3 +1,4 @@
# -*- encoding: UTF-8 -*-
# Copyright 2015, Rackspace, US, Inc. # Copyright 2015, Rackspace, US, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -22,6 +23,16 @@ filter_regex = re.compile(
r"""{\$\s*('([^']|\\')+'|"([^"]|\\")+")\s*\|\s*translate\s*\$}""" r"""{\$\s*('([^']|\\')+'|"([^"]|\\")+")\s*\|\s*translate\s*\$}"""
) )
# browser innerHTML decodes some html entities automatically, so when
# we extract the msgid and want to match what Javascript sees, we need
# to leave some entities alone, but decode all the rest. Add entries
# to HTML_ENTITIES as necessary.
HTML_ENTITY_PASSTHROUGH = {'amp', 'gt', 'lt'}
HTML_ENTITY_DECODED = {
'reg': u'®',
'times': u'×'
}
class AngularGettextHTMLParser(html_parser.HTMLParser): class AngularGettextHTMLParser(html_parser.HTMLParser):
"""Parse HTML to find translate directives. """Parse HTML to find translate directives.
@ -68,7 +79,10 @@ class AngularGettextHTMLParser(html_parser.HTMLParser):
if attr == 'translate-comment': if attr == 'translate-comment':
self.comments.append(value) self.comments.append(value)
elif self.in_translate: elif self.in_translate:
self.data += '<%s>' % tag s = tag
if attrs:
s += ' ' + ' '.join('%s="%s"' % a for a in attrs)
self.data += '<%s>' % s
self.inner_tags.append(tag) self.inner_tags.append(tag)
else: else:
for attr in attrs: for attr in attrs:
@ -89,6 +103,21 @@ class AngularGettextHTMLParser(html_parser.HTMLParser):
(self.line, u'gettext', match[0][1:-1], []) (self.line, u'gettext', match[0][1:-1], [])
) )
def handle_entityref(self, name):
if self.in_translate:
if name in HTML_ENTITY_PASSTHROUGH:
self.data += '&%s;' % name
else:
self.data += HTML_ENTITY_DECODED[name]
def handle_charref(self, name):
if self.in_translate:
self.data += '&#%s;' % name
def handle_comment(self, comment):
if self.in_translate:
self.data += '<!--%s-->' % comment
def handle_endtag(self, tag): def handle_endtag(self, tag):
if self.in_translate: if self.in_translate:
if len(self.inner_tags) > 0: if len(self.inner_tags) > 0:

View File

@ -26,7 +26,7 @@
<div class="form-group"> <div class="form-group">
<label class="control-label" translate>Container Access</label> <label class="control-label" translate>Container Access</label>
<div> <div>
<label for="id_public" translate> <label for="id_public">
<input type="checkbox" ng-model="ctrl.model.public" <input type="checkbox" ng-model="ctrl.model.public"
name="public" checked id="id_public"> name="public" checked id="id_public">
<span translate>Public</span> <span translate>Public</span>