pax_global_header 0000666 0000000 0000000 00000000064 13433453626 0014523 g ustar 00root root 0000000 0000000 52 comment=a3b00b81749a88f53d5f1129941e60f7c0683788
django-js-asset-1.2.2/ 0000775 0000000 0000000 00000000000 13433453626 0014516 5 ustar 00root root 0000000 0000000 django-js-asset-1.2.2/.gitignore 0000664 0000000 0000000 00000000230 13433453626 0016501 0 ustar 00root root 0000000 0000000 *.py?
*~
*.sw?
\#*#
/secrets.py
.DS_Store
._*
/*.egg-info
/MANIFEST
/_build
/build
/dist
tests/test.zip
/docs/_build
/.eggs
.coverage
htmlcov
venv
.tox
django-js-asset-1.2.2/.travis.yml 0000664 0000000 0000000 00000003065 13433453626 0016633 0 ustar 00root root 0000000 0000000 dist: xenial
sudo: false
language: python
python:
- 3.7
matrix:
fast_finish: true
include:
- python: 3.7
env: REQ="https://github.com/django/django/archive/master.zip#egg=Django"
- python: 3.7
env: REQ="Django>=2.2a1,<3.0"
- python: 3.6
env: REQ="Django>=2.2a1,<3.0"
- python: 3.5
env: REQ="Django>=2.2a1,<3.0"
- python: 3.7
env: REQ="Django>=2.1,<2.2"
- python: 3.7
env: REQ="Django>=2.0,<2.1"
- python: 3.7
env: REQ="Django>=1.11,<2.0"
- python: 3.6
env: REQ="Django>=1.11,<2.0"
- python: 3.5
env: REQ="Django>=1.11,<2.0"
- python: 3.4
env: REQ="Django>=1.11,<2.0"
- python: 2.7
env: REQ="Django>=1.11,<2.0"
- python: 3.5
env: REQ="Django>=1.10,<1.11"
- python: 2.7
env: REQ="Django>=1.10,<1.11"
- python: 3.5
env: REQ="Django>=1.9,<1.10"
- python: 2.7
env: REQ="Django>=1.9,<1.10"
- python: 3.5
env: REQ="Django>=1.8,<1.9"
- python: 3.4
env: REQ="Django>=1.8,<1.9"
- python: 2.7
env: REQ="Django>=1.8,<1.9"
- python: 3.4
env: REQ="Django>=1.7,<1.8"
- python: 2.7
env: REQ="Django>=1.7,<1.8"
- python: 3.7
env: REQ="black flake8"
install:
- pip install black flake8
script:
- flake8 .
- black --check js_asset tests
allow_failures:
- env: REQ="https://github.com/django/django/archive/master.zip#egg=Django"
install:
- pip install $REQ coverage pytz
- python setup.py install
script: cd tests && ./manage.py test -v2 testapp
django-js-asset-1.2.2/CHANGELOG.rst 0000664 0000000 0000000 00000003515 13433453626 0016543 0 ustar 00root root 0000000 0000000
.. _changelog:
Change log
==========
`Next version`_
~~~~~~~~~~~~~~~
- Made ``JS()`` objects hashable so that they can be put into sets in
preparation for a possible fix for media ordering in Django #30179.
`1.2`_ (2019-02-08)
~~~~~~~~~~~~~~~~~~~
- Reformatted the code using Black.
- Added equality of ``JS()`` objects to avoid adding the same script
more than once in the same configuration.
- Determine the ``static`` callable at module import time, not each time
a static path is generated.
- Customized the ``repr()`` of ``JS()`` objects.
- Added Python 3.7 and Django 2.2 to the test matrix.
`1.1`_ (2018-04-19)
~~~~~~~~~~~~~~~~~~~
- Added support for skipping ``static()``, mostly useful when adding
external scripts via ``JS()`` (e.g for adding ``defer="defer"``).
- Made the attributes dictionary optional.
`1.0`_ (2018-01-16)
~~~~~~~~~~~~~~~~~~~
- Added an export of the ``js_asset.static()`` helper (which does the
right thing regarding ``django.contrib.staticfiles``)
- Fixed the documentation to not mention internal (and removed) API of
Django's ``Media()`` class.
- Switched to using tox_ for running tests and style checks locally.
- Added more versions of Python and Django to the CI matrix.
`0.1`_ (2017-04-19)
~~~~~~~~~~~~~~~~~~~
- Initial public release extracted from django-content-editor_.
.. _Django: https://www.djangoproject.com/
.. _django-content-editor: https://django-content-editor.readthedocs.io/
.. _tox: https://tox.readthedocs.io/
.. _0.1: https://github.com/matthiask/django-js-asset/commit/e335c79a87
.. _1.0: https://github.com/matthiask/django-js-asset/compare/0.1...1.0
.. _1.1: https://github.com/matthiask/django-js-asset/compare/1.0...1.1
.. _1.2: https://github.com/matthiask/django-js-asset/compare/1.1...1.2
.. _Next version: https://github.com/matthiask/django-js-asset/compare/1.2...master
django-js-asset-1.2.2/LICENSE 0000664 0000000 0000000 00000003016 13433453626 0015523 0 ustar 00root root 0000000 0000000 Copyright (c) 2016, FEINHEIT AG and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of FEINHEIT GmbH nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
django-js-asset-1.2.2/MANIFEST.in 0000664 0000000 0000000 00000000246 13433453626 0016256 0 ustar 00root root 0000000 0000000 include LICENSE
include MANIFEST.in
include README.rst
recursive-include js_asset/static *
recursive-include js_asset/locale *
recursive-include js_asset/templates *
django-js-asset-1.2.2/README.rst 0000664 0000000 0000000 00000004254 13433453626 0016212 0 ustar 00root root 0000000 0000000 ===============================================================================
django-js-asset -- script tag with additional attributes for django.forms.Media
===============================================================================
.. image:: https://travis-ci.org/matthiask/django-js-asset.svg?branch=master
:target: https://travis-ci.org/matthiask/django-js-asset
Usage
=====
Use this to insert a script tag via ``forms.Media`` containing additional
attributes (such as ``id`` and ``data-*`` for CSP-compatible data
injection.):
.. code-block:: python
from js_asset import JS
forms.Media(js=[
JS("asset.js", {
"id": "asset-script",
"data-answer": "42",
}),
])
The rendered media tag (via ``{{ media.js }}`` or ``{{ media }}`` will
now contain a script tag as follows, without line breaks:
.. code-block:: html
The attributes are automatically escaped. The data attributes may now be
accessed inside ``asset.js``:
.. code-block:: javascript
var answer = document.querySelector("#asset-script").dataset.answer;
Also, because the implementation of ``static`` differs between supported
Django versions (older do not take the presence of
``django.contrib.staticfiles`` in ``INSTALLED_APPS`` into account), a
``js_asset.static`` function is provided which does the right thing
automatically.
When adding external script assets, you should pass ``static=False`` to
the ``JS`` object to avoid passing the script URL through ``static()``.
In this case, you probably want to add ``defer`` or ``async``, and maybe
also ``integrity`` and ``crossorigin`` attributes. Please note that
boolean attributes are not properly supported, so specify them as
follows::
JS(
"https://cdn.example.com/script.js",
{"defer": "defer"},
static=False,
)
Compatibility
=============
At the time of writing this app is compatible with Django 1.7 and better
(up to and including the Django master branch), but have a look at the
`Travis CI build `_ for
definitive answers.
django-js-asset-1.2.2/js_asset/ 0000775 0000000 0000000 00000000000 13433453626 0016331 5 ustar 00root root 0000000 0000000 django-js-asset-1.2.2/js_asset/__init__.py 0000664 0000000 0000000 00000000327 13433453626 0020444 0 ustar 00root root 0000000 0000000 from __future__ import absolute_import, unicode_literals
VERSION = (1, 2, 2)
__version__ = ".".join(map(str, VERSION))
try:
from js_asset.js import * # noqa
except ImportError: # pragma: no cover
pass
django-js-asset-1.2.2/js_asset/js.py 0000664 0000000 0000000 00000004623 13433453626 0017324 0 ustar 00root root 0000000 0000000 from __future__ import unicode_literals
import json
from django import VERSION
from django.apps import apps
from django.forms.utils import flatatt
from django.templatetags.static import static
from django.utils.html import format_html, mark_safe
__all__ = ("JS", "static")
if VERSION < (1, 10): # pragma: no cover
_static = static
def static(path):
if apps.is_installed("django.contrib.staticfiles"):
from django.contrib.staticfiles.storage import staticfiles_storage
return staticfiles_storage.url(path)
return _static(path)
class JS(object):
"""
Use this to insert a script tag via ``forms.Media`` containing additional
attributes (such as ``id`` and ``data-*`` for CSP-compatible data
injection.)::
forms.Media(js=[
JS('asset.js', {
'id': 'asset-script',
'data-answer': '"42"',
}),
])
The rendered media tag (via ``{{ media.js }}`` or ``{{ media }}`` will
now contain a script tag as follows, without line breaks::
The attributes are automatically escaped. The data attributes may now be
accessed inside ``asset.js``::
var answer = document.querySelector('#asset-script').dataset.answer;
"""
def __init__(self, js, attrs=None, static=True):
self.js = js
self.attrs = attrs or {}
self.static = static
def startswith(self, _):
# Masquerade as absolute path so that we are returned as-is.
return True
def __repr__(self):
return "JS({}, {}, static={})".format(
self.js, json.dumps(self.attrs, sort_keys=True), self.static
)
def __html__(self):
js = static(self.js) if self.static else self.js
return (
format_html('{}"{}', js, mark_safe(flatatt(self.attrs)))[:-1]
if self.attrs
else js
)
def __eq__(self, other):
if isinstance(other, JS):
return (
self.js == other.js
and self.attrs == other.attrs
and self.static == other.static
)
return self.js == other and not self.attrs and self.static
def __hash__(self):
return hash((self.js, json.dumps(self.attrs, sort_keys=True), self.static))
django-js-asset-1.2.2/setup.cfg 0000664 0000000 0000000 00000000337 13433453626 0016342 0 ustar 00root root 0000000 0000000 [flake8]
exclude=venv,build,docs,.tox
ignore=E203,W503
max-complexity=10
max-line-length=88
[bdist_wheel]
universal = 1
[coverage:run]
branch = True
include =
*js_asset*
omit =
*migrations*
*tests*
*.tox*
django-js-asset-1.2.2/setup.py 0000775 0000000 0000000 00000002604 13433453626 0016235 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
from io import open
import os
from setuptools import setup, find_packages
def read(filename):
path = os.path.join(os.path.dirname(__file__), filename)
with open(path, encoding="utf-8") as handle:
return handle.read()
setup(
name="django-js-asset",
version=__import__("js_asset").__version__,
description="script tag with additional attributes for django.forms.Media",
long_description=read("README.rst"),
author="Matthias Kestenholz",
author_email="mk@feinheit.ch",
url="https://github.com/matthiask/django-js-asset/",
license="BSD License",
platforms=["OS Independent"],
packages=find_packages(exclude=["tests"]),
include_package_data=True,
classifiers=[
# 'Development Status :: 5 - Production/Stable',
"Environment :: Web Environment",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Software Development",
"Topic :: Software Development :: Libraries :: Application Frameworks",
],
zip_safe=False,
tests_require=["Django", "coverage", "pytz"],
)
django-js-asset-1.2.2/tests/ 0000775 0000000 0000000 00000000000 13433453626 0015660 5 ustar 00root root 0000000 0000000 django-js-asset-1.2.2/tests/.gitignore 0000664 0000000 0000000 00000000024 13433453626 0017644 0 ustar 00root root 0000000 0000000 /.coverage
/htmlcov
django-js-asset-1.2.2/tests/cov.sh 0000775 0000000 0000000 00000000202 13433453626 0017000 0 ustar 00root root 0000000 0000000 #!/bin/sh
venv/bin/coverage run --branch --include="*js_asset/*" --omit="*tests*" ./manage.py test testapp
venv/bin/coverage html
django-js-asset-1.2.2/tests/manage.py 0000775 0000000 0000000 00000000535 13433453626 0017470 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
import os
import sys
from os.path import abspath, dirname
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testapp.settings")
sys.path.insert(0, dirname(dirname(abspath(__file__))))
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
django-js-asset-1.2.2/tests/requirements.txt 0000664 0000000 0000000 00000000020 13433453626 0021134 0 ustar 00root root 0000000 0000000 Django
coverage
django-js-asset-1.2.2/tests/testapp/ 0000775 0000000 0000000 00000000000 13433453626 0017340 5 ustar 00root root 0000000 0000000 django-js-asset-1.2.2/tests/testapp/__init__.py 0000664 0000000 0000000 00000000000 13433453626 0021437 0 ustar 00root root 0000000 0000000 django-js-asset-1.2.2/tests/testapp/settings.py 0000664 0000000 0000000 00000000273 13433453626 0021554 0 ustar 00root root 0000000 0000000 DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
INSTALLED_APPS = ["django.contrib.staticfiles"]
STATIC_URL = "/static/"
SECRET_KEY = "supersikret"
django-js-asset-1.2.2/tests/testapp/test_js_asset.py 0000664 0000000 0000000 00000004577 13433453626 0022601 0 ustar 00root root 0000000 0000000 from __future__ import unicode_literals
from django.forms import Media
from django.test import TestCase
from js_asset.js import JS
class AssetTest(TestCase):
def test_asset(self):
media = Media(
css={"print": ["app/print.css"]},
js=[
"app/test.js",
JS("app/asset.js", {"id": "asset-script", "data-the-answer": 42}),
JS("app/asset-without.js", {}),
],
)
html = "%s" % media
# print(html)
self.assertInHTML(
'', # noqa
html,
)
self.assertInHTML(
'', # noqa
html,
)
self.assertInHTML(
'', # noqa
html,
)
self.assertInHTML(
'', # noqa
html,
)
def test_absolute(self):
media = Media(js=[JS("https://cdn.example.org/script.js", static=False)])
html = "%s" % media
self.assertInHTML(
'', # noqa
html,
)
def test_asset_merging(self):
media1 = Media(js=["thing.js", JS("other.js"), "some.js"])
media2 = Media(js=["thing.js", JS("other.js"), "some.js"])
media = media1 + media2
self.assertEqual(len(media._js), 3)
self.assertEqual(media._js[0], "thing.js")
self.assertEqual(media._js[2], "some.js")
def test_repr(self):
self.assertEqual(
repr(
JS("app/asset.js", {"id": "asset-script", "data-the-answer": 42})
).lstrip("u"),
'JS(app/asset.js, {"data-the-answer": 42, "id": "asset-script"}, static=True)', # noqa
)
def test_set(self):
media = [
JS("app/asset.js", {"id": "asset-script", "data-the-answer": 42}),
JS("app/asset.js", {"id": "asset-script", "data-the-answer": 42}),
JS("app/asset.js", {"id": "asset-script", "data-the-answer": 43}),
]
self.assertEqual(len(set(media)), 2)
django-js-asset-1.2.2/tox.ini 0000664 0000000 0000000 00000001202 13433453626 0016024 0 ustar 00root root 0000000 0000000 [testenv]
basepython = python3
[testenv:style]
deps =
black
flake8
changedir = {toxinidir}
commands =
black setup.py js_asset tests
flake8 .
skip_install = true
# [testenv:docs]
# deps = Sphinx
# changedir = docs
# commands = make html
# skip_install = true
# whitelist_externals = make
[testenv:tests]
deps =
Django
coverage
changedir = {toxinidir}
skip_install = true
commands =
coverage run tests/manage.py test -v 2 testapp
coverage html
[testenv:tests-old]
basepython = python2
deps =
Django<1.8
changedir = {toxinidir}
skip_install = true
commands =
python tests/manage.py test -v 2 testapp