mirror of https://github.com/django/django.git
parent
847171b0d0
commit
926e18d7d1
|
@ -4,6 +4,7 @@ import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from gzip import GzipFile
|
from gzip import GzipFile
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.functional import allow_lazy, SimpleLazyObject
|
from django.utils.functional import allow_lazy, SimpleLazyObject
|
||||||
|
@ -327,6 +328,11 @@ ustring_re = re.compile("([\u0080-\uffff])")
|
||||||
|
|
||||||
|
|
||||||
def javascript_quote(s, quote_double_quotes=False):
|
def javascript_quote(s, quote_double_quotes=False):
|
||||||
|
msg = (
|
||||||
|
"django.utils.text.javascript_quote() is deprecated. "
|
||||||
|
"Use django.utils.html.escapejs() instead."
|
||||||
|
)
|
||||||
|
warnings.warn(msg, PendingDeprecationWarning, stacklevel=2)
|
||||||
|
|
||||||
def fix(match):
|
def fix(match):
|
||||||
return "\\u%04x" % ord(match.group(1))
|
return "\\u%04x" % ord(match.group(1))
|
||||||
|
|
|
@ -119,6 +119,8 @@ details on these changes.
|
||||||
* ``ssi`` and ``url`` template tags will be removed from the ``future`` template
|
* ``ssi`` and ``url`` template tags will be removed from the ``future`` template
|
||||||
tag library (used during the 1.3/1.4 deprecation period).
|
tag library (used during the 1.3/1.4 deprecation period).
|
||||||
|
|
||||||
|
* ``django.utils.text.javascript_quote`` will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-1.8:
|
.. _deprecation-removed-in-1.8:
|
||||||
|
|
||||||
1.8
|
1.8
|
||||||
|
|
|
@ -1374,3 +1374,15 @@ Django 1.3 introduced ``{% load ssi from future %}`` and
|
||||||
:ttag:`ssi` and :ttag:`url` template tags. This syntax is now deprecated and
|
:ttag:`ssi` and :ttag:`url` template tags. This syntax is now deprecated and
|
||||||
will be removed in Django 1.9. You can simply remove the
|
will be removed in Django 1.9. You can simply remove the
|
||||||
``{% load ... from future %}`` tags.
|
``{% load ... from future %}`` tags.
|
||||||
|
|
||||||
|
``django.utils.text.javascript_quote``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
``javascript_quote()`` was an undocumented function present in ``django.utils.text``.
|
||||||
|
It was used internally in the :ref:`javascript_catalog view <javascript_catalog-view>`
|
||||||
|
whose implementation was changed to make use of ``json.dumps()`` instead.
|
||||||
|
If you were relying on this function to provide safe output from untrusted
|
||||||
|
strings, you should use ``django.utils.html.escapejs`` or the
|
||||||
|
:tfilter:`escapejs` template filter.
|
||||||
|
If all you need is to generate valid javascript strings, you can simply use
|
||||||
|
``json.dumps()``.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from unittest import skipUnless
|
from unittest import skipUnless
|
||||||
|
import warnings
|
||||||
|
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils import six, text
|
from django.utils import six, text
|
||||||
|
@ -152,16 +153,26 @@ class TestUtilsText(SimpleTestCase):
|
||||||
def test_javascript_quote(self):
|
def test_javascript_quote(self):
|
||||||
input = "<script>alert('Hello \\xff.\n Welcome\there\r');</script>"
|
input = "<script>alert('Hello \\xff.\n Welcome\there\r');</script>"
|
||||||
output = r"<script>alert(\'Hello \\xff.\n Welcome\there\r\');<\/script>"
|
output = r"<script>alert(\'Hello \\xff.\n Welcome\there\r\');<\/script>"
|
||||||
|
with warnings.catch_warnings():
|
||||||
self.assertEqual(text.javascript_quote(input), output)
|
self.assertEqual(text.javascript_quote(input), output)
|
||||||
|
|
||||||
# Exercising quote_double_quotes keyword argument
|
# Exercising quote_double_quotes keyword argument
|
||||||
input = '"Text"'
|
input = '"Text"'
|
||||||
|
with warnings.catch_warnings():
|
||||||
self.assertEqual(text.javascript_quote(input), '"Text"')
|
self.assertEqual(text.javascript_quote(input), '"Text"')
|
||||||
self.assertEqual(text.javascript_quote(input, quote_double_quotes=True),
|
self.assertEqual(text.javascript_quote(input, quote_double_quotes=True),
|
||||||
'"Text"')
|
'"Text"')
|
||||||
|
|
||||||
@skipUnless(IS_WIDE_BUILD)
|
@skipUnless(IS_WIDE_BUILD, 'Not running in a wide build of Python')
|
||||||
def test_javascript_quote_unicode(self):
|
def test_javascript_quote_unicode(self):
|
||||||
input = "<script>alert('Hello \\xff.\n Wel𝕃come\there\r');</script>"
|
input = "<script>alert('Hello \\xff.\n Wel𝕃come\there\r');</script>"
|
||||||
output = r"<script>alert(\'Hello \\xff.\n Wel𝕃come\there\r\');<\/script>"
|
output = r"<script>alert(\'Hello \\xff.\n Wel𝕃come\there\r\');<\/script>"
|
||||||
|
with warnings.catch_warnings():
|
||||||
self.assertEqual(text.javascript_quote(input), output)
|
self.assertEqual(text.javascript_quote(input), output)
|
||||||
|
|
||||||
|
def test_deprecation(self):
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
text.javascript_quote('thingy')
|
||||||
|
self.assertEqual(len(w), 1)
|
||||||
|
self.assertIn('escapejs()', repr(w[0].message))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
import gettext
|
import gettext
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -11,7 +12,6 @@ from django.test import (
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.translation import override
|
from django.utils.translation import override
|
||||||
from django.utils.text import javascript_quote
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from selenium.webdriver.firefox import webdriver as firefox
|
from selenium.webdriver.firefox import webdriver as firefox
|
||||||
|
@ -63,8 +63,8 @@ class I18NTests(TestCase):
|
||||||
response = self.client.get('/jsi18n/')
|
response = self.client.get('/jsi18n/')
|
||||||
# response content must include a line like:
|
# response content must include a line like:
|
||||||
# "this is to be translated": <value of trans_txt Python variable>
|
# "this is to be translated": <value of trans_txt Python variable>
|
||||||
# javascript_quote is used to be able to check unicode strings
|
# json.dumps() is used to be able to check unicode strings
|
||||||
self.assertContains(response, javascript_quote(trans_txt), 1)
|
self.assertContains(response, json.dumps(trans_txt), 1)
|
||||||
if lang_code == 'fr':
|
if lang_code == 'fr':
|
||||||
# Message with context (msgctxt)
|
# Message with context (msgctxt)
|
||||||
self.assertContains(response, r'"month name\u0004May": "mai"', 1)
|
self.assertContains(response, r'"month name\u0004May": "mai"', 1)
|
||||||
|
@ -120,7 +120,7 @@ class JsI18NTests(TestCase):
|
||||||
"""
|
"""
|
||||||
with self.settings(LANGUAGE_CODE='fr'), override('en-us'):
|
with self.settings(LANGUAGE_CODE='fr'), override('en-us'):
|
||||||
response = self.client.get('/jsi18n_english_translation/')
|
response = self.client.get('/jsi18n_english_translation/')
|
||||||
self.assertContains(response, javascript_quote('this app0 string is to be translated'))
|
self.assertContains(response, 'this app0 string is to be translated')
|
||||||
|
|
||||||
def testI18NLanguageNonEnglishFallback(self):
|
def testI18NLanguageNonEnglishFallback(self):
|
||||||
"""
|
"""
|
||||||
|
@ -165,7 +165,7 @@ class JsI18NTestsMultiPackage(TestCase):
|
||||||
"""
|
"""
|
||||||
with self.settings(LANGUAGE_CODE='en-us'), override('fr'):
|
with self.settings(LANGUAGE_CODE='en-us'), override('fr'):
|
||||||
response = self.client.get('/jsi18n_multi_packages1/')
|
response = self.client.get('/jsi18n_multi_packages1/')
|
||||||
self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1'))
|
self.assertContains(response, 'il faut traduire cette cha\\u00eene de caract\\u00e8res de app1')
|
||||||
|
|
||||||
@modify_settings(INSTALLED_APPS={'append': ['view_tests.app3', 'view_tests.app4']})
|
@modify_settings(INSTALLED_APPS={'append': ['view_tests.app3', 'view_tests.app4']})
|
||||||
def testI18NDifferentNonEnLangs(self):
|
def testI18NDifferentNonEnLangs(self):
|
||||||
|
@ -175,7 +175,7 @@ class JsI18NTestsMultiPackage(TestCase):
|
||||||
"""
|
"""
|
||||||
with self.settings(LANGUAGE_CODE='fr'), override('es-ar'):
|
with self.settings(LANGUAGE_CODE='fr'), override('es-ar'):
|
||||||
response = self.client.get('/jsi18n_multi_packages2/')
|
response = self.client.get('/jsi18n_multi_packages2/')
|
||||||
self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido'))
|
self.assertContains(response, 'este texto de app3 debe ser traducido')
|
||||||
|
|
||||||
def testI18NWithLocalePaths(self):
|
def testI18NWithLocalePaths(self):
|
||||||
extended_locale_paths = settings.LOCALE_PATHS + (
|
extended_locale_paths = settings.LOCALE_PATHS + (
|
||||||
|
@ -185,7 +185,7 @@ class JsI18NTestsMultiPackage(TestCase):
|
||||||
with override('es-ar'):
|
with override('es-ar'):
|
||||||
response = self.client.get('/jsi18n/')
|
response = self.client.get('/jsi18n/')
|
||||||
self.assertContains(response,
|
self.assertContains(response,
|
||||||
javascript_quote('este texto de app3 debe ser traducido'))
|
'este texto de app3 debe ser traducido')
|
||||||
|
|
||||||
|
|
||||||
skip_selenium = not os.environ.get('DJANGO_SELENIUM_TESTS', False)
|
skip_selenium = not os.environ.get('DJANGO_SELENIUM_TESTS', False)
|
||||||
|
|
Loading…
Reference in New Issue