Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #19136 -- Properly escape gettext context prefixes in the i18n …

…JavaScript view template.
  • Loading branch information...
commit 4a5e8087ac7676ef08e76275c1f756778b39c13e 1 parent 44046e8
Jannis Leidel jezdez authored
8 django/views/i18n.py
View
@@ -99,16 +99,16 @@ def get_formats():
function gettext_noop(msgid) { return msgid; }
function pgettext(context, msgid) {
- var value = gettext(context + '\x04' + msgid);
- if (value.indexOf('\x04') != -1) {
+ var value = gettext(context + '\\x04' + msgid);
+ if (value.indexOf('\\x04') != -1) {
value = msgid;
}
return value;
}
function npgettext(context, singular, plural, count) {
- var value = ngettext(context + '\x04' + singular, context + '\x04' + plural, count);
- if (value.indexOf('\x04') != -1) {
+ var value = ngettext(context + '\\x04' + singular, context + '\\x04' + plural, count);
+ if (value.indexOf('\\x04') != -1) {
value = ngettext(singular, plural, count);
}
return value;
BIN  tests/regressiontests/views/locale/de/LC_MESSAGES/djangojs.mo
View
Binary file not shown
40 tests/regressiontests/views/locale/de/LC_MESSAGES/djangojs.po
View
@@ -0,0 +1,40 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: django tests\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-02-14 17:33+0100\n"
+"PO-Revision-Date: 2011-01-21 21:37-0300\n"
+"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
+"Language-Team: de <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: models.py:7
+msgctxt "month name"
+msgid "May"
+msgstr "Mai"
+
+#: models.py:9
+msgctxt "verb"
+msgid "May"
+msgstr "Kann"
+
+#: models.py:11
+msgid "%s item"
+msgid_plural "%s items"
+msgstr[0] "%s Element"
+msgstr[1] "%s Elemente"
+
+#: models.py:11
+msgctxt "search"
+msgid "%s result"
+msgid_plural "%s results"
+msgstr[0] "%s Resultat"
+msgstr[1] "%s Resultate"
44 tests/regressiontests/views/templates/jsi18n.html
View
@@ -0,0 +1,44 @@
+<html>
+<head>
+ <script type="text/javascript" src="/jsi18n_admin/"></script>
+</head>
+
+<body>
+ <p id="gettext">
+ <script type="text/javascript">
+ document.write(gettext("Remove"));
+ </script>
+ </p>
+
+ <p id="ngettext_sing">
+ <script type="text/javascript">
+ document.write(interpolate(ngettext("%s item", "%s items", 1), [1]));
+ </script>
+ </p>
+
+ <p id="ngettext_plur">
+ <script type="text/javascript">
+ document.write(interpolate(ngettext("%s item", "%s items", 455), [455]));
+ </script>
+ </p>
+
+ <p id="pgettext">
+ <script type="text/javascript">
+ document.write(pgettext("verb", "May"));
+ </script>
+ </p>
+
+ <p id="npgettext_sing">
+ <script type="text/javascript">
+ document.write(interpolate(npgettext("search", "%s result", "%s results", 1), [1]));
+ </script>
+ </p>
+
+ <p id="npgettext_plur">
+ <script type="text/javascript">
+ document.write(interpolate(npgettext("search", "%s result", "%s results", 455), [455]));
+ </script>
+ </p>
+
+</body>
+</html>
2  tests/regressiontests/views/tests/__init__.py
View
@@ -4,7 +4,7 @@
ExceptionReporterTests, PlainTextReportTests, ExceptionReporterFilterTests,
AjaxResponseExceptionReporterFilter)
from .defaults import DefaultsTests
-from .i18n import JsI18NTests, I18NTests, JsI18NTestsMultiPackage
+from .i18n import JsI18NTests, I18NTests, JsI18NTestsMultiPackage, JavascriptI18nTests
from .shortcuts import ShortcutTests
from .specials import URLHandling
from .static import StaticHelperTest, StaticUtilsTests, StaticTests
52 tests/regressiontests/views/tests/i18n.py
View
@@ -6,11 +6,17 @@
from django.conf import settings
from django.core.urlresolvers import reverse
-from django.test import TestCase
-from django.utils import six
-from django.utils.translation import override, get_language
+from django.test import LiveServerTestCase, TestCase
+from django.test.utils import override_settings
+from django.utils import six, unittest
+from django.utils.translation import override
from django.utils.text import javascript_quote
+try:
+ from selenium.webdriver.firefox import webdriver as firefox
+except ImportError:
+ firefox = None
+
from ..urls import locale_dir
@@ -152,3 +158,43 @@ def testI18NWithLocalePaths(self):
response = self.client.get('/views/jsi18n/')
self.assertContains(response,
javascript_quote('este texto de app3 debe ser traducido'))
+
+
+@unittest.skipUnless(firefox, 'Selenium not installed')
+class JavascriptI18nTests(LiveServerTestCase):
+ urls = 'regressiontests.views.urls'
+
+ @classmethod
+ def setUpClass(cls):
+ cls.selenium = firefox.WebDriver()
+ super(JavascriptI18nTests, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.selenium.quit()
+ super(JavascriptI18nTests, cls).tearDownClass()
+
+ @override_settings(LANGUAGE_CODE='de')
+ def test_javascript_gettext(self):
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views']
+ with self.settings(INSTALLED_APPS=extended_apps):
+ self.selenium.get('%s%s' % (self.live_server_url, '/jsi18n_template/'))
+
+ elem = self.selenium.find_element_by_id("gettext")
+ self.assertEqual(elem.text, u"Entfernen")
+ elem = self.selenium.find_element_by_id("ngettext_sing")
+ self.assertEqual(elem.text, "1 Element")
+ elem = self.selenium.find_element_by_id("ngettext_plur")
+ self.assertEqual(elem.text, "455 Elemente")
+ elem = self.selenium.find_element_by_id("pgettext")
+ self.assertEqual(elem.text, "Kann")
+ elem = self.selenium.find_element_by_id("npgettext_sing")
+ self.assertEqual(elem.text, "1 Resultat")
+ elem = self.selenium.find_element_by_id("npgettext_plur")
+ self.assertEqual(elem.text, "455 Resultate")
+
+ def test_escaping(self):
+ extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.views']
+ with self.settings(INSTALLED_APPS=extended_apps):
+ response = self.client.get('%s%s' % (self.live_server_url, '/jsi18n_admin/'))
+ self.assertContains(response, '\\x04')
7 tests/regressiontests/views/urls.py
View
@@ -32,6 +32,11 @@
'packages': ('regressiontests.views.app3', 'regressiontests.views.app4'),
}
+js_info_dict_admin = {
+ 'domain': 'djangojs',
+ 'packages': ('django.contrib.admin', 'regressiontests.views'),
+}
+
urlpatterns = patterns('',
(r'^$', views.index_page),
@@ -51,6 +56,8 @@
(r'^jsi18n_english_translation/$', 'django.views.i18n.javascript_catalog', js_info_dict_english_translation),
(r'^jsi18n_multi_packages1/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages1),
(r'^jsi18n_multi_packages2/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages2),
+ (r'^jsi18n_admin/$', 'django.views.i18n.javascript_catalog', js_info_dict_admin),
+ (r'^jsi18n_template/$', views.jsi18n),
# Static views
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': media_dir}),
3  tests/regressiontests/views/views.py
View
@@ -51,6 +51,9 @@ def template_exception(request, n):
return render_to_response('debug/template_exception.html',
{'arg': except_args[int(n)]})
+def jsi18n(request):
+ return render_to_response('jsi18n.html')
+
# Some views to exercise the shortcuts
def render_to_response_view(request):
Please sign in to comment.
Something went wrong with that request. Please try again.