fix(gettext): extract template-literal translations with correct line numbers (#38063)
This commit is contained in:
parent
b60a980fd4
commit
163094c898
2 changed files with 44 additions and 17 deletions
|
|
@ -185,27 +185,40 @@ def parse_template_string(
|
||||||
:param options: a dictionary of additional options (optional)
|
:param options: a dictionary of additional options (optional)
|
||||||
:param lineno: starting line number (optional)
|
:param lineno: starting line number (optional)
|
||||||
"""
|
"""
|
||||||
from babel.messages.jslexer import line_re
|
|
||||||
|
|
||||||
prev_character = None
|
prev_character = None
|
||||||
|
current_lineno = lineno
|
||||||
level = 0
|
level = 0
|
||||||
inside_str = False
|
inside_expression_str = False
|
||||||
|
expression_lineno = lineno
|
||||||
expression_contents = ""
|
expression_contents = ""
|
||||||
for character in template_string[1:-1]:
|
for character in template_string[1:-1]:
|
||||||
if not inside_str and character in ('"', "'", "`"):
|
if not level:
|
||||||
inside_str = character
|
|
||||||
elif inside_str == character and prev_character != r"\\":
|
|
||||||
inside_str = False
|
|
||||||
if level:
|
|
||||||
expression_contents += character
|
|
||||||
if not inside_str:
|
|
||||||
if character == "{" and prev_character == "$":
|
if character == "{" and prev_character == "$":
|
||||||
|
expression_lineno = current_lineno
|
||||||
level += 1
|
level += 1
|
||||||
elif level and character == "}":
|
else:
|
||||||
level -= 1
|
expression_contents += character
|
||||||
if level == 0 and expression_contents:
|
|
||||||
expression_contents = expression_contents[:-1]
|
if inside_expression_str:
|
||||||
yield from extract_javascript(expression_contents, keywords, options, lineno)
|
if inside_expression_str == character and prev_character != r"\\":
|
||||||
lineno += len(line_re.findall(expression_contents))
|
inside_expression_str = False
|
||||||
expression_contents = ""
|
else:
|
||||||
|
if character in ('"', "'", "`"):
|
||||||
|
inside_expression_str = character
|
||||||
|
elif character == "{":
|
||||||
|
level += 1
|
||||||
|
elif character == "}":
|
||||||
|
level -= 1
|
||||||
|
if level == 0 and expression_contents:
|
||||||
|
expression_contents = expression_contents[:-1]
|
||||||
|
yield from extract_javascript(
|
||||||
|
expression_contents,
|
||||||
|
keywords,
|
||||||
|
options,
|
||||||
|
expression_lineno,
|
||||||
|
)
|
||||||
|
expression_contents = ""
|
||||||
|
inside_expression_str = False
|
||||||
|
if character == "\n":
|
||||||
|
current_lineno += 1
|
||||||
prev_character = character
|
prev_character = character
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,17 @@ class TestJavaScript(IntegrationTestCase):
|
||||||
next(extract_javascript(code)),
|
next(extract_javascript(code)),
|
||||||
(1, "__", ("Test", None, "Context")),
|
(1, "__", ("Test", None, "Context")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_extract_javascript_from_template_literal_attribute(self):
|
||||||
|
code = "let test = `<button title=\"${__('In attribute')}\">${__('In text')}</button>`;"
|
||||||
|
self.assertEqual(
|
||||||
|
list(extract_javascript(code)),
|
||||||
|
[(1, "__", "In attribute"), (1, "__", "In text")],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_extract_javascript_template_literal_multiline_line_numbers(self):
|
||||||
|
code = "let test = `\n<button title=\"${__('In attribute')}\">\n ${__('In text')}\n</button>\n`;"
|
||||||
|
self.assertEqual(
|
||||||
|
list(extract_javascript(code)),
|
||||||
|
[(2, "__", "In attribute"), (3, "__", "In text")],
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue