diff --git a/frappe/gettext/extractors/javascript.py b/frappe/gettext/extractors/javascript.py
index 5c273ff502..1b3c64b215 100644
--- a/frappe/gettext/extractors/javascript.py
+++ b/frappe/gettext/extractors/javascript.py
@@ -185,27 +185,40 @@ def parse_template_string(
:param options: a dictionary of additional options (optional)
:param lineno: starting line number (optional)
"""
- from babel.messages.jslexer import line_re
-
prev_character = None
+ current_lineno = lineno
level = 0
- inside_str = False
+ inside_expression_str = False
+ expression_lineno = lineno
expression_contents = ""
for character in template_string[1:-1]:
- if not inside_str and character in ('"', "'", "`"):
- inside_str = character
- elif inside_str == character and prev_character != r"\\":
- inside_str = False
- if level:
- expression_contents += character
- if not inside_str:
+ if not level:
if character == "{" and prev_character == "$":
+ expression_lineno = current_lineno
level += 1
- elif level and character == "}":
- level -= 1
- if level == 0 and expression_contents:
- expression_contents = expression_contents[:-1]
- yield from extract_javascript(expression_contents, keywords, options, lineno)
- lineno += len(line_re.findall(expression_contents))
- expression_contents = ""
+ else:
+ expression_contents += character
+
+ if inside_expression_str:
+ if inside_expression_str == character and prev_character != r"\\":
+ inside_expression_str = False
+ 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
diff --git a/frappe/gettext/extractors/tests/test_javascript.py b/frappe/gettext/extractors/tests/test_javascript.py
index 876ea5db14..be6f9721e0 100644
--- a/frappe/gettext/extractors/tests/test_javascript.py
+++ b/frappe/gettext/extractors/tests/test_javascript.py
@@ -15,3 +15,17 @@ class TestJavaScript(IntegrationTestCase):
next(extract_javascript(code)),
(1, "__", ("Test", None, "Context")),
)
+
+ def test_extract_javascript_from_template_literal_attribute(self):
+ code = "let test = ``;"
+ 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\n`;"
+ self.assertEqual(
+ list(extract_javascript(code)),
+ [(2, "__", "In attribute"), (3, "__", "In text")],
+ )