8 Commits

Author SHA1 Message Date
Embrace
ed8dc195fb Updated manifest.json and serviceworker by adding scope parameter. 2019-03-07 07:52:15 -03:00
Embrace
f2fdf0c123 CHANGELOG updated 2019-02-11 07:43:32 -02:00
Silvio Luis
b1c697c1de Merge pull request #7 from Setti7/master
Fix problem of multiple service workers being registered over multiple URLs
2019-02-11 07:33:13 -02:00
André Setti
d687b0c047 Fixed tests 2019-02-09 01:37:58 -02:00
André Setti
ab8db72bd3 Fix problem of multiple service workers being registered
Source:
https://stackoverflow.com/questions/33816342/how-to-prevent-the-same-service-worker-from-registering-over-multiple-pages
2019-02-08 02:20:26 -02:00
Embrace
2326895768 Restored support to oldest Django versions 2019-02-01 10:16:52 -02:00
Embrace
053afe1bc0 Added the splash screen for iOS and Meta tags to Android and Win8 2019-01-23 12:01:00 -02:00
Embrace
d86732bb9a Readme updated 2018-12-17 07:48:17 -02:00
23 changed files with 217 additions and 59 deletions

View File

@@ -6,14 +6,16 @@
## 1.0.0 ## 1.0.0
### Added
- Unit tests - Unit tests
- Add Oritentation on manifest.json - Option `Oritentation` on manifest.json
- Add tox - tox.ini
- Add Coverage - Coverage
## 1.0.1 ## 1.0.1
### Added
- Add django 2 requirement - Add django 2 requirement
- Use templateviews instead of own implementations - Use templateviews instead of own implementations
- Add content_types - Add content_types
@@ -22,5 +24,38 @@
- Add default_config in `__init__.py` - Add default_config in `__init__.py`
- Add basic serviceworker - Add basic serviceworker
- Add default offline page and default icons - Add default offline page and default icons
### Changed
- Updated the unit tests - Updated the unit tests
## 1.0.2
### Fixed
- Fix tox.ini to install pypandoc
### Added
- The support to splash screen for iOS Meta tags `apple-touch-startup-image`
- Meta tag `mobile-web-app-capable`
- Meta tag `application-name`
- Meta tag `msapplication-TileColor` and `msapplication-TileImage` for win8
- Meta tag `rel="icon"` with default icon
- Images for splash screen
- Include the new images to `serviceworker.js`
### Changed
- Update `CHANGELOG.md`
- Update `README.md`
## 1.0.3
### Fixed
- Restored support to oldest Django versions
## 1.0.4
### Fixed
- Fix problem of multiple service workers being registered over multiple URLs
## 1.0.5
### Added
- Updated manifest.json by adding scope parameter.
- Updated serviceworker.js add scope dynamic parameter

View File

@@ -3,8 +3,9 @@ django-pwa
[![Build Status](https://travis-ci.org/silviolleite/django-pwa.svg)](https://travis-ci.org/silviolleite/django-pwa) [![Build Status](https://travis-ci.org/silviolleite/django-pwa.svg)](https://travis-ci.org/silviolleite/django-pwa)
[![Maintainability](https://api.codeclimate.com/v1/badges/246542ea921058c4f76f/maintainability)](https://codeclimate.com/github/silviolleite/django-pwa/maintainability) [![Maintainability](https://api.codeclimate.com/v1/badges/246542ea921058c4f76f/maintainability)](https://codeclimate.com/github/silviolleite/django-pwa/maintainability)
[![codecov](https://codecov.io/gh/silviolleite/django-pwa/branch/master/graph/badge.svg)](https://codecov.io/gh/silviolleite/django-pwa) [![codecov](https://codecov.io/gh/silviolleite/django-pwa/branch/master/graph/badge.svg)](https://codecov.io/gh/silviolleite/django-pwa)
[![PyPI - Downloads](https://img.shields.io/pypi/dd/django-pwa.svg)](https://pypi.org/project/django-pwa/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/django-pwa.svg)](https://pypi.org/project/django-pwa/)
[![PyPI - Downloads](https://img.shields.io/pypi/v/django-pwa.svg)](https://pypi.org/project/django-pwa) [![PyPI - Downloads](https://img.shields.io/pypi/v/django-pwa.svg)](https://pypi.org/project/django-pwa)
[![PyPI - Downloads](https://img.shields.io/pypi/djversions/django-pwa.svg)](https://pypi.org/project/django-pwa)
This Django app turns your project into a [progressive web app](https://developers.google.com/web/progressive-web-apps/). Navigating to your site on an Android phone will prompt you to add the app to your home screen. This Django app turns your project into a [progressive web app](https://developers.google.com/web/progressive-web-apps/). Navigating to your site on an Android phone will prompt you to add the app to your home screen.
@@ -36,13 +37,15 @@ INSTALLED_APPS = [
] ]
``` ```
Configure your app name, description, and icons in settings.py: Configure your app name, description, icons and splash screen images in settings.py:
```python ```python
PWA_APP_NAME = 'My App' PWA_APP_NAME = 'My App'
PWA_APP_DESCRIPTION = "My app description" PWA_APP_DESCRIPTION = "My app description"
PWA_APP_THEME_COLOR = '#0A0302' PWA_APP_THEME_COLOR = '#0A0302'
PWA_APP_BACKGROUND_COLOR = '#ffffff' PWA_APP_BACKGROUND_COLOR = '#ffffff'
PWA_APP_DISPLAY = 'standalone' PWA_APP_DISPLAY = 'standalone'
PWA_APP_SCOPE = '/',
PWA_APP_ORIENTATION = 'any' PWA_APP_ORIENTATION = 'any'
PWA_APP_START_URL = '/' PWA_APP_START_URL = '/'
PWA_APP_ICONS = [ PWA_APP_ICONS = [
@@ -51,20 +54,26 @@ PWA_APP_ICONS = [
'sizes': '160x160' 'sizes': '160x160'
} }
] ]
PWA_APP_SPLASH_SCREEN = [
{
'src': '/static/images/icons/splash-640x1136.png',
'media': '(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)'
}
]
PWA_APP_DIR = 'ltr' PWA_APP_DIR = 'ltr'
PWA_APP_LANG = 'en-US' PWA_APP_LANG = 'en-US'
``` ```
All settings are optional, and the app will work fine with its internal defaults. Highly recommend setting at least `PWA_APP_NAME` and `PWA_APP_DESCRIPTION`. All settings are optional, and the app will work fine with its internal defaults. Highly recommend setting at least `PWA_APP_NAME`, `PWA_APP_DESCRIPTION`, `PWA_APP_ICONS` and `PWA_APP_SPLASH_SCREEN`.
Add the progressive web app URLs to urls.py: Add the progressive web app URLs to urls.py:
```python ```python
from django.urls import path, include from django.urls import url, include
urlpatterns = [ urlpatterns = [
... ...
path('', include('pwa.urls')), # You MUST use an empty string as the URL prefix url('', include('pwa.urls')), # You MUST use an empty string as the URL prefix
... ...
] ]
``` ```
@@ -109,6 +118,16 @@ var filesToCache = [
'/images/icons/icon-192x192.png', '/images/icons/icon-192x192.png',
'/images/icons/icon-384x384.png', '/images/icons/icon-384x384.png',
'/images/icons/icon-512x512.png', '/images/icons/icon-512x512.png',
'/static/images/icons/splash-640x1136.png',
'/static/images/icons/splash-750x1334.png',
'/static/images/icons/splash-1242x2208.png',
'/static/images/icons/splash-1125x2436.png',
'/static/images/icons/splash-828x1792.png',
'/static/images/icons/splash-1242x2688.png',
'/static/images/icons/splash-1536x2048.png',
'/static/images/icons/splash-1668x2224.png',
'/static/images/icons/splash-1668x2388.png',
'/static/images/icons/splash-2048x2732.png'
]; ];
// Cache on install // Cache on install
@@ -152,10 +171,10 @@ self.addEventListener("fetch", event => {
Adding Your Own Service Worker Adding Your Own Service Worker
===== =====
By default, the service worker implemented by this app is empty. To add service worker functionality, you'll want to create a `serviceworker.js` or similarly named template in a template directory, and then point at it using the PWA_SERVICE_WORKER_PATH variable (PWA_APP_FETCH_URL is passed through). To add service worker functionality, you'll want to create a `serviceworker.js` or similarly named template in a template directory, and then point at it using the PWA_SERVICE_WORKER_PATH variable (PWA_APP_FETCH_URL is passed through).
```python ```python
PWA_SERVICE_WORKER_PATH = 'my_app/serviceworker.js' PWA_SERVICE_WORKER_PATH = os.path.join(BASE_DIR, 'my_app', 'serviceworker.js')
``` ```

View File

@@ -3,8 +3,9 @@ from django.conf import settings
import os import os
# Path to the service worker implementation. Default implementation is empty. # Path to the service worker implementation. Default implementation is empty.
PWA_SERVICE_WORKER_PATH = getattr(settings, 'PWA_SERVICE_WORKER_PATH', 'serviceworker.js') PWA_SERVICE_WORKER_PATH = getattr(settings, 'PWA_SERVICE_WORKER_PATH',
os.path.join(os.path.abspath(os.path.dirname(__file__)), 'templates',
'serviceworker.js'))
# App parameters to include in manifest.json and appropriate meta tags # App parameters to include in manifest.json and appropriate meta tags
PWA_APP_NAME = getattr(settings, 'PWA_APP_NAME', 'MyApp') PWA_APP_NAME = getattr(settings, 'PWA_APP_NAME', 'MyApp')
PWA_APP_DESCRIPTION = getattr(settings, 'PWA_APP_DESCRIPTION', 'My Progressive Web App') PWA_APP_DESCRIPTION = getattr(settings, 'PWA_APP_DESCRIPTION', 'My Progressive Web App')
@@ -12,43 +13,87 @@ PWA_APP_ROOT_URL = getattr(settings, 'PWA_APP_ROOT_URL', '/')
PWA_APP_THEME_COLOR = getattr(settings, 'PWA_APP_THEME_COLOR', '#000') PWA_APP_THEME_COLOR = getattr(settings, 'PWA_APP_THEME_COLOR', '#000')
PWA_APP_BACKGROUND_COLOR = getattr(settings, 'PWA_APP_BACKGROUND_COLOR', '#fff') PWA_APP_BACKGROUND_COLOR = getattr(settings, 'PWA_APP_BACKGROUND_COLOR', '#fff')
PWA_APP_DISPLAY = getattr(settings, 'PWA_APP_DISPLAY', 'standalone') PWA_APP_DISPLAY = getattr(settings, 'PWA_APP_DISPLAY', 'standalone')
PWA_APP_SCOPE = getattr(settings, 'PWA_APP_SCOPE', '/')
PWA_APP_ORIENTATION = getattr(settings, 'PWA_APP_ORIENTATION', 'any') PWA_APP_ORIENTATION = getattr(settings, 'PWA_APP_ORIENTATION', 'any')
PWA_APP_START_URL = getattr(settings, 'PWA_APP_START_URL', '/') PWA_APP_START_URL = getattr(settings, 'PWA_APP_START_URL', '/')
PWA_APP_FETCH_URL = getattr(settings, 'PWA_APP_FETCH_URL', '/') PWA_APP_FETCH_URL = getattr(settings, 'PWA_APP_FETCH_URL', '/')
PWA_APP_ICONS = getattr(settings, 'PWA_APP_ICONS', [ PWA_APP_ICONS = getattr(settings, 'PWA_APP_ICONS', [
{ {
'src': '/static/images/icons/icon-72x72.png', 'src': '/static/images/icons/icon-72x72.png',
'sizes': '72x72' 'size': '72x72'
}, },
{ {
'src': '/static/images/icons/icon-96x96.png', 'src': '/static/images/icons/icon-96x96.png',
'sizes': '96x96' 'size': '96x96'
}, },
{ {
'src': '/static/images/icons/icon-128x128.png', 'src': '/static/images/icons/icon-128x128.png',
'sizes': '128x128' 'size': '128x128'
}, },
{ {
'src': '/static/images/icons/icon-144x144.png', 'src': '/static/images/icons/icon-144x144.png',
'sizes': '144x144' 'size': '144x144'
}, },
{ {
'src': '/static/images/icons/icon-152x152.png', 'src': '/static/images/icons/icon-152x152.png',
'sizes': '152x152' 'size': '152x152'
}, },
{ {
'src': '/static/images/icons/icon-192x192.png', 'src': '/static/images/icons/icon-192x192.png',
'sizes': '192x192' 'size': '192x192'
}, },
{ {
'src': '/static/images/icons/icon-384x384.png', 'src': '/static/images/icons/icon-384x384.png',
'sizes': '384x384' 'size': '384x384'
}, },
{ {
'src': '/static/images/icons/icon-512x512.png', 'src': '/static/images/icons/icon-512x512.png',
'sizes': '512x512' 'size': '512x512'
} }
]) ])
PWA_APP_SPLASH_SCREEN = getattr(settings, 'PWA_APP_SPLASH_SCREEN', [
{
'src': '/static/images/icons/splash-640x1136.png',
'media': '(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-750x1334.png',
'media': '(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-1242x2208.png',
'media': '(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)'
},
{
'src': '/static/images/icons/splash-1125x2436.png',
'media': '(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)'
},
{
'src': '/static/images/icons/splash-828x1792.png',
'media': '(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-1242x2688.png',
'media': '(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)'
},
{
'src': '/static/images/icons/splash-1536x2048.png',
'media': '(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-1668x2224.png',
'media': '(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-1668x2388.png',
'media': '(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)'
},
{
'src': '/static/images/icons/splash-2048x2732.png',
'media': '(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)'
}
])
PWA_APP_DIR = getattr(settings, 'PWA_APP_DIR', 'auto') PWA_APP_DIR = getattr(settings, 'PWA_APP_DIR', 'auto')
PWA_APP_LANG = getattr(settings, 'PWA_APP_LANG', 'en-US') PWA_APP_LANG = getattr(settings, 'PWA_APP_LANG', 'en-US')

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -5,6 +5,7 @@
"description": {{ PWA_APP_DESCRIPTION|js }}, "description": {{ PWA_APP_DESCRIPTION|js }},
"start_url": {{ PWA_APP_START_URL|js }}, "start_url": {{ PWA_APP_START_URL|js }},
"display": {{ PWA_APP_DISPLAY|js }}, "display": {{ PWA_APP_DISPLAY|js }},
"scope": {{ PWA_APP_SCOPE|js }},
"orientation": {{ PWA_APP_ORIENTATION|js }}, "orientation": {{ PWA_APP_ORIENTATION|js }},
"background_color": {{ PWA_APP_BACKGROUND_COLOR|js }}, "background_color": {{ PWA_APP_BACKGROUND_COLOR|js }},
"theme_color": {{ PWA_APP_THEME_COLOR|js }}, "theme_color": {{ PWA_APP_THEME_COLOR|js }},

View File

@@ -1,27 +1,48 @@
<!-- Path to manifest.json --> <!-- Path to manifest.json -->
<link rel="manifest" href="/manifest.json"> <link rel="manifest" href="/manifest.json">
<!-- Icons for Apple Devices --> <!-- Add to homescreen for Chrome on Android -->
{% for icon in PWA_APP_ICONS %} <meta name="mobile-web-app-capable" content="yes">
<link rel="apple-touch-icon" href="{{ icon.src }}" sizes="{{ icon.sizes }}"> <meta name="application-name" content="{{ PWA_APP_NAME }}">
{% endfor %}
<!-- Chrome for Android theme color -->
<meta name="theme-color" content="{{ PWA_APP_THEME_COLOR }}"> <meta name="theme-color" content="{{ PWA_APP_THEME_COLOR }}">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="{{ PWA_APP_NAME }}"> <meta name="apple-mobile-web-app-title" content="{{ PWA_APP_NAME }}">
<meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="apple-mobile-web-app-status-bar-style" content="default">
{% for icon in PWA_APP_ICONS %}
<link rel="apple-touch-icon" href="{{ icon.src }}" sizes="{{ icon.size }}">
{% endfor %}
{% for splash in PWA_APP_SPLASH_SCREEN%}
<link href="{{ splash.src }}" media="{{ splash.media }}" rel="apple-touch-startup-image"/>
{% endfor %}
<!-- Tile for Win8 -->
<meta name="msapplication-TileColor" content="{{ PWA_APP_BACKGROUND_COLOR }}">
{% with PWA_APP_ICONS|last as icon %}
<meta name="msapplication-TileImage" content="{{ icon.src }}">
<link rel="icon" sizes="{{ icon.size }}" href="{{ icon.src }}">
{% endwith %}
<script type="text/javascript"> <script type="text/javascript">
// Initialize the service worker // Initialize the service worker
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/serviceworker.js', { navigator.serviceWorker.register('/serviceworker.js', {
scope: '.' // <--- THIS BIT IS REQUIRED scope: '{{ PWA_APP_SCOPE }}'
}).then(function (registration) { }).then(function (registration) {
// Registration was successful // Registration was successful
console.log('django-progressive-web-app: ServiceWorker registration successful with scope: ', registration.scope); console.log('django-pwa: ServiceWorker registration successful with scope: ', registration.scope);
}, function (err) { }, function (err) {
// registration failed :( // registration failed :(
console.log('django-progressive-web-app: ServiceWorker registration failed: ', err); console.log('django-pwa: ServiceWorker registration failed: ', err);
}); });
} }
</script> </script>

View File

@@ -12,6 +12,16 @@ var filesToCache = [
'/static/images/icons/icon-192x192.png', '/static/images/icons/icon-192x192.png',
'/static/images/icons/icon-384x384.png', '/static/images/icons/icon-384x384.png',
'/static/images/icons/icon-512x512.png', '/static/images/icons/icon-512x512.png',
'/static/images/icons/splash-640x1136.png',
'/static/images/icons/splash-750x1334.png',
'/static/images/icons/splash-1242x2208.png',
'/static/images/icons/splash-1125x2436.png',
'/static/images/icons/splash-828x1792.png',
'/static/images/icons/splash-1242x2688.png',
'/static/images/icons/splash-1536x2048.png',
'/static/images/icons/splash-1668x2224.png',
'/static/images/icons/splash-1668x2388.png',
'/static/images/icons/splash-2048x2732.png'
]; ];
// Cache on install // Cache on install

View File

@@ -1,10 +1,10 @@
from django.urls import path from django.conf.urls import url
from .views import Manifest, ServiceWorker, OfflineView from .views import manifest, service_worker, offline
# Serve up serviceworker.js and manifest.json at the root # Serve up serviceworker.js and manifest.json at the root
urlpatterns = [ urlpatterns = [
path('serviceworker.js', ServiceWorker.as_view(), name='serviceworker'), url('^serviceworker.js$', service_worker, name='serviceworker'),
path('manifest.json', Manifest.as_view(), name='manifest'), url('^manifest.json$', manifest, name='manifest'),
path('offline', OfflineView.as_view(), name='offline') url('^offline/$', offline, name='offline')
] ]

View File

@@ -1,27 +1,21 @@
from django.views.generic.base import TemplateView from django.http import HttpResponse
from django.shortcuts import render
from . import app_settings from . import app_settings
class ServiceWorker(TemplateView): def service_worker(request):
content_type = 'application/javascript' response = HttpResponse(open(app_settings.PWA_SERVICE_WORKER_PATH).read(), content_type='application/javascript')
template_name = app_settings.PWA_SERVICE_WORKER_PATH return response
def get_context_data(self, **kwargs):
kwargs['PWA_APP_FETCH_URL'] = app_settings.PWA_APP_FETCH_URL
return super().get_context_data(**kwargs)
class Manifest(TemplateView): def manifest(request):
content_type = 'application/json' return render(request, 'manifest.json', {
template_name = 'manifest.json' setting_name: getattr(app_settings, setting_name)
for setting_name in dir(app_settings)
def get_context_data(self, **kwargs): if setting_name.startswith('PWA_')
for setting_name in dir(app_settings): })
if setting_name.startswith('PWA_'):
kwargs[setting_name] = getattr(app_settings, setting_name)
return super().get_context_data(**kwargs)
class OfflineView(TemplateView): def offline(request):
template_name = "offline.html" return render(request, "offline.html")

View File

@@ -17,12 +17,12 @@ except RuntimeError:
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
install_requirements = [ install_requirements = [
"django>=2", "django>=1.8",
] ]
setup( setup(
name='django-pwa', name='django-pwa',
version='1.0.1', version='1.0.5',
packages=find_packages(), packages=find_packages(),
install_requires=install_requirements, install_requires=install_requirements,
include_package_data=True, include_package_data=True,
@@ -35,6 +35,10 @@ setup(
classifiers=[ classifiers=[
'Environment :: Web Environment', 'Environment :: Web Environment',
'Framework :: Django', 'Framework :: Django',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0', 'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1', 'Framework :: Django :: 2.1',
'Intended Audience :: Developers', 'Intended Audience :: Developers',

View File

@@ -12,6 +12,7 @@ class AppSettingsTest(TestCase):
'PWA_APP_ROOT_URL', 'PWA_APP_ROOT_URL',
'PWA_APP_THEME_COLOR', 'PWA_APP_THEME_COLOR',
'PWA_APP_BACKGROUND_COLOR', 'PWA_APP_BACKGROUND_COLOR',
'PWA_APP_SCOPE',
'PWA_APP_DISPLAY', 'PWA_APP_DISPLAY',
'PWA_APP_ORIENTATION', 'PWA_APP_ORIENTATION',
'PWA_APP_START_URL', 'PWA_APP_START_URL',

View File

@@ -23,10 +23,25 @@ class CreateMetaTemplateTagTest(TestCase):
'<link rel="apple-touch-icon" href="/static/images/icons/icon-384x384.png" sizes="384x384">', '<link rel="apple-touch-icon" href="/static/images/icons/icon-384x384.png" sizes="384x384">',
'<link rel="apple-touch-icon" href="/static/images/icons/icon-512x512.png" sizes="512x512">', '<link rel="apple-touch-icon" href="/static/images/icons/icon-512x512.png" sizes="512x512">',
'<link rel="manifest" href="/manifest.json">', '<link rel="manifest" href="/manifest.json">',
'<meta name="mobile-web-app-capable" content="yes">',
'<meta name="theme-color" content="#000">', '<meta name="theme-color" content="#000">',
'<meta name="apple-mobile-web-app-capable" content="yes">', '<meta name="apple-mobile-web-app-capable" content="yes">',
'<meta name="apple-mobile-web-app-title" content="MyApp">', '<meta name="apple-mobile-web-app-title" content="MyApp">',
'<meta name="apple-mobile-web-app-status-bar-style" content="default">' '<meta name="application-name" content="MyApp">',
'<meta name="apple-mobile-web-app-status-bar-style" content="default">',
'<link rel="icon" sizes="512x512" href="/static/images/icons/icon-512x512.png">',
'<link href="/static/images/icons/splash-640x1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-750x1334.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1242x2208.png" media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1125x2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-828x1792.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1242x2688.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1536x2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1668x2224.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-1668x2388.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<link href="/static/images/icons/splash-2048x2732.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>',
'<meta name="msapplication-TileColor" content="#fff">',
'<meta name="msapplication-TileImage" content="/static/images/icons/icon-512x512.png">'
] ]
for text in tags: for text in tags:
with self.subTest(): with self.subTest():
@@ -38,11 +53,11 @@ class CreateMetaTemplateTagTest(TestCase):
'<script type="text/javascript">', '<script type="text/javascript">',
"if ('serviceWorker' in navigator) {", "if ('serviceWorker' in navigator) {",
"navigator.serviceWorker.register('/serviceworker.js', {", "navigator.serviceWorker.register('/serviceworker.js', {",
"scope: '.'", "scope: '/'",
"}).then(function (registration) {", "}).then(function (registration) {",
"console.log('django-progressive-web-app: ServiceWorker registration successful with scope: ', registration.scope);", "console.log('django-pwa: ServiceWorker registration successful with scope: ', registration.scope);",
"}, function (err) {", "}, function (err) {",
"console.log('django-progressive-web-app: ServiceWorker registration failed: ', err);", "console.log('django-pwa: ServiceWorker registration failed: ', err);",
"});", "});",
"</script>" "</script>"
] ]

View File

@@ -31,6 +31,7 @@ class ManifestTest(TestCase):
'"description":', '"description":',
'"start_url":', '"start_url":',
'"display":', '"display":',
'"scope":',
'"background_color":', '"background_color":',
'"theme_color":', '"theme_color":',
'"orientation":', '"orientation":',

16
tox.ini
View File

@@ -1,14 +1,26 @@
[tox] [tox]
envlist = envlist =
py35-django{18,19,110,111,20,21}
py36-django{20} py36-django{20}
py36-django{21} py36-django{21}
py37-django{20}
py37-django{21}
[testenv] [testenv]
commands = python runtests.py commands = python runtests.py
setenv = setenv =
DJANGO_SETTINGS_MODULE=tests.settings DJANGO_SETTINGS_MODULE=tests.settings
PYTHONPATH={toxinidir} PYTHONPATH={toxinidir}
basepython = py36: python3.6 basepython =
py35: python3.5
py36: python3.6
py37: python3.7
deps = deps =
django18: django==1.8
django19: django==1.9
django110: django==1.10
django111: django==1.11
django20: Django==2.0 django20: Django==2.0
django21: Django==2.1 django21: Django==2.1
pypandoc==1.3.3