├── .gitignore ├── .jslintrc ├── .travis.yml ├── AUTHORS.rst ├── CONTRIBUTING.rst ├── HISTORY.rst ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── django_jsonschema_widget ├── __init__.py ├── apps.py ├── static │ └── django-jsonschema-widget │ │ ├── css │ │ ├── jsonschema_widget.css │ │ └── lib │ │ │ ├── advanced-mode.css │ │ │ ├── img │ │ │ └── jsoneditor-icons.svg │ │ │ └── jsonschema-ui.css │ │ └── js │ │ ├── jsonschema_widget.js │ │ ├── lib │ │ ├── advanced-mode.js │ │ ├── jsonschema-ui.js │ │ └── tomorrow_night_bright.js │ │ └── widget.js ├── templates │ └── django_jsonschema_widget │ │ └── base.html ├── urls.py └── widgets.py ├── docs ├── Makefile ├── authors.rst ├── conf.py ├── contributing.rst ├── history.rst ├── index.rst ├── installation.rst ├── make.bat ├── readme.rst └── usage.rst ├── requirements-dev.txt ├── requirements-test.txt ├── requirements.txt ├── runtests.py ├── setup.cfg ├── setup.py ├── tests ├── __init__.py ├── manage.py ├── settings.py ├── test_models.py └── urls.py └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *.cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # Jupyter Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # SageMath parsed files 79 | *.sage.py 80 | 81 | # dotenv 82 | .env 83 | 84 | # virtualenv 85 | .venv 86 | venv/ 87 | ENV/ 88 | 89 | # Spyder project settings 90 | .spyderproject 91 | .spyproject 92 | 93 | # Rope project settings 94 | .ropeproject 95 | 96 | # mkdocs documentation 97 | /site 98 | 99 | # mypy 100 | .mypy_cache/ 101 | -------------------------------------------------------------------------------- /.jslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "navigator", 5 | "console", 6 | "window", 7 | "django", 8 | "$", 9 | "gettext", 10 | "alert", 11 | "closePreview", 12 | "objectIsEqual", 13 | "editor", 14 | "advancedJSONEditor", 15 | "JSONEditor" 16 | ], 17 | 18 | "browser": true, 19 | "eqeq": true, 20 | "white": true, 21 | "unparam": true, 22 | "undef": true, 23 | "sub": true, 24 | "asi": true, 25 | "sloppy": true, 26 | "vars": true, 27 | "forin": true, 28 | "nomen": true, 29 | "continue": true, 30 | "plusplus": true, 31 | "newcap": true, 32 | "indent": 4, 33 | "maxerr": 10000 34 | } 35 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | sudo: false 3 | cache: pip 4 | 5 | python: 6 | - "3.6" 7 | - "2.7" 8 | 9 | env: 10 | - DJANGO="django>=2.1,<2.2" 11 | - DJANGO="django>=2.0,<2.1" 12 | - DJANGO="django>=1.11,<2.0" 13 | 14 | matrix: 15 | exclude: 16 | - python: "2.7" 17 | env: DJANGO="django>=2.0,<2.1" 18 | env: DJANGO="django>=2.1,<2.2" 19 | 20 | branches: 21 | only: 22 | - master 23 | 24 | before_install: 25 | - pip install -U pip wheel setuptools 26 | - pip install --no-cache-dir -U -r requirements-test.txt 27 | - npm install -g jslint 28 | - jslint django_jsonschema_widget/static/django-jsonschema-widget/js/*.js 29 | 30 | install: 31 | - pip install $DJANGO 32 | - python setup.py -q develop 33 | 34 | script: 35 | - coverage run --source= runtests.py 36 | 37 | - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 38 | # gets commit message of last commit before pull request merge 39 | COMMIT_MESSAGE=$(git log $TRAVIS_PULL_REQUEST_SHA --format=%B -n 1) 40 | printf "Checking commit message:\n\n" 41 | printf "$COMMIT_MESSAGE\n\n" 42 | checkcommit --message "$COMMIT_MESSAGE" 43 | fi 44 | 45 | after_success: 46 | coveralls 47 | -------------------------------------------------------------------------------- /AUTHORS.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Credits 3 | ======= 4 | 5 | Development Lead 6 | ---------------- 7 | 8 | * `Federico Capoano `_ 9 | 10 | Contributors 11 | ------------ 12 | 13 | * `Asif Saif Uddin `_ -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Contributing 3 | ============ 4 | 5 | Contributions are welcome, and they are greatly appreciated! Every 6 | little bit helps, and credit will always be given. 7 | 8 | You can contribute in many ways: 9 | 10 | Types of Contributions 11 | ---------------------- 12 | 13 | Report Bugs 14 | ~~~~~~~~~~~ 15 | 16 | Report bugs at https://github.com/openwisp/django-jsonschema-widget/issues. 17 | 18 | If you are reporting a bug, please include: 19 | 20 | * Your operating system name and version. 21 | * Any details about your local setup that might be helpful in troubleshooting. 22 | * Detailed steps to reproduce the bug. 23 | 24 | Fix Bugs 25 | ~~~~~~~~ 26 | 27 | Look through the GitHub issues for bugs. Anything tagged with "bug" 28 | is open to whoever wants to implement it. 29 | 30 | Implement Features 31 | ~~~~~~~~~~~~~~~~~~ 32 | 33 | Look through the GitHub issues for features. Anything tagged with "feature" 34 | is open to whoever wants to implement it. 35 | 36 | Write Documentation 37 | ~~~~~~~~~~~~~~~~~~~ 38 | 39 | django-jsonschema-widget could always use more documentation, whether as part of the 40 | official django-jsonschema-widget docs, in docstrings, or even on the web in blog posts, 41 | articles, and such. 42 | 43 | Submit Feedback 44 | ~~~~~~~~~~~~~~~ 45 | 46 | The best way to send feedback is to file an issue at https://github.com/openwisp/django-jsonschema-widget/issues. 47 | 48 | If you are proposing a feature: 49 | 50 | * Explain in detail how it would work. 51 | * Keep the scope as narrow as possible, to make it easier to implement. 52 | * Remember that this is a volunteer-driven project, and that contributions 53 | are welcome :) 54 | 55 | Get Started! 56 | ------------ 57 | 58 | Ready to contribute? Here's how to set up `django-jsonschema-widget` for local development. 59 | 60 | 1. Fork the `django-jsonschema-widget` repo on GitHub. 61 | 2. Clone your fork locally:: 62 | 63 | $ git clone https://github.com/your_name_here/django-jsonschema-widget.git 64 | 65 | 3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: 66 | 67 | $ mkvirtualenv django-jsonschema-widget 68 | $ cd django-jsonschema-widget/ 69 | $ python setup.py develop 70 | 71 | 4. Create a branch for local development:: 72 | 73 | $ git checkout -b name-of-your-bugfix-or-feature 74 | 75 | Now you can make your changes locally. 76 | 77 | 5. When you're done making changes, check that your changes pass flake8 and the 78 | tests, including testing other Python versions with tox:: 79 | 80 | $ flake8 jsonschema_widget tests 81 | $ python setup.py test 82 | $ tox 83 | 84 | To get flake8 and tox, just pip install them into your virtualenv. 85 | 86 | 6. Commit your changes and push your branch to GitHub:: 87 | 88 | $ git add . 89 | $ git commit -m "Your detailed description of your changes." 90 | $ git push origin name-of-your-bugfix-or-feature 91 | 92 | 7. Submit a pull request through the GitHub website. 93 | 94 | Pull Request Guidelines 95 | ----------------------- 96 | 97 | Before you submit a pull request, check that it meets these guidelines: 98 | 99 | 1. The pull request should include tests. 100 | 2. If the pull request adds functionality, the docs should be updated. Put 101 | your new functionality into a function with a docstring, and add the 102 | feature to the list in README.rst. 103 | 3. The pull request should work for Python 2.7, and 3.5+, and for PyPy. Check 104 | https://travis-ci.org/openwisp/django-jsonschema-widget/pull_requests 105 | and make sure that the tests pass for all supported Python versions. 106 | 107 | Tips 108 | ---- 109 | 110 | To run a subset of tests:: 111 | 112 | $ python -m unittest tests.test_jsonschema_widget 113 | -------------------------------------------------------------------------------- /HISTORY.rst: -------------------------------------------------------------------------------- 1 | .. :changelog: 2 | 3 | History 4 | ------- 5 | 6 | 0.1.0 (2018-04-16) 7 | ++++++++++++++++++ 8 | 9 | * First release on PyPI. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, OpenWISP 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS.rst 2 | include CONTRIBUTING.rst 3 | include HISTORY.rst 4 | include LICENSE 5 | include README.rst 6 | recursive-include jsonschema_widget *.html *.png *.gif *js *.css *jpg *jpeg *svg *py 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean-pyc clean-build docs help 2 | .DEFAULT_GOAL := help 3 | define BROWSER_PYSCRIPT 4 | import os, webbrowser, sys 5 | try: 6 | from urllib import pathname2url 7 | except: 8 | from urllib.request import pathname2url 9 | 10 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 11 | endef 12 | export BROWSER_PYSCRIPT 13 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 14 | 15 | help: 16 | @grep '^[a-zA-Z]' $(MAKEFILE_LIST) | sort | awk -F ':.*?## ' 'NF==2 {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}' 17 | 18 | clean: clean-build clean-pyc 19 | 20 | clean-build: ## remove build artifacts 21 | rm -fr build/ 22 | rm -fr dist/ 23 | rm -fr *.egg-info 24 | 25 | clean-pyc: ## remove Python file artifacts 26 | find . -name '*.pyc' -exec rm -f {} + 27 | find . -name '*.pyo' -exec rm -f {} + 28 | find . -name '*~' -exec rm -f {} + 29 | 30 | lint: ## check style with flake8 31 | flake8 jsonschema_widget tests 32 | 33 | test: ## run tests quickly with the default Python 34 | python runtests.py tests 35 | 36 | test-all: ## run tests on every Python version with tox 37 | tox 38 | 39 | coverage: ## check code coverage quickly with the default Python 40 | coverage run --source jsonschema_widget runtests.py tests 41 | coverage report -m 42 | coverage html 43 | open htmlcov/index.html 44 | 45 | docs: ## generate Sphinx HTML documentation, including API docs 46 | rm -f docs/django-jsonschema-widget.rst 47 | rm -f docs/modules.rst 48 | sphinx-apidoc -o docs/ jsonschema_widget 49 | $(MAKE) -C docs clean 50 | $(MAKE) -C docs html 51 | $(BROWSER) docs/_build/html/index.html 52 | 53 | release: clean ## package and upload a release 54 | python setup.py sdist upload 55 | python setup.py bdist_wheel upload 56 | 57 | sdist: clean ## package 58 | python setup.py sdist 59 | ls -l dist 60 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | django-jsonschema-widget 3 | ============================= 4 | 5 | .. image:: https://badge.fury.io/py/django-jsonschema-widget.svg 6 | :target: https://badge.fury.io/py/django-jsonschema-widget 7 | 8 | .. image:: https://travis-ci.org/openwisp/django-jsonschema-widget.svg?branch=master 9 | :target: https://travis-ci.org/openwisp/django-jsonschema-widget 10 | 11 | .. image:: https://codecov.io/gh/openwisp/django-jsonschema-widget/branch/master/graph/badge.svg 12 | :target: https://codecov.io/gh/openwisp/django-jsonschema-widget 13 | 14 | Configuration widget for embedded device. 15 | 16 | Documentation 17 | ------------- 18 | 19 | The full documentation is at https://django-jsonschema-widget.readthedocs.io. 20 | 21 | Quickstart 22 | ---------- 23 | 24 | Install django-jsonschema-widget:: 25 | 26 | pip install django-jsonschema-widget 27 | 28 | Add it to your `INSTALLED_APPS`: 29 | 30 | .. code-block:: python 31 | 32 | INSTALLED_APPS = ( 33 | ... 34 | 'django_jsonschema_widget.apps.JsonschemaWidgetConfig', 35 | ... 36 | ) 37 | 38 | Add django-jsonschema-widget's URL patterns: 39 | 40 | .. code-block:: python 41 | 42 | from django_jsonschema_widget import urls as jsonschema_widget_urls 43 | 44 | 45 | urlpatterns = [ 46 | ... 47 | url(r'^', include(jsonschema_widget_urls)), 48 | ... 49 | ] 50 | 51 | Features 52 | -------- 53 | 54 | * TODO 55 | 56 | Running Tests 57 | ------------- 58 | 59 | Does the code actually work? 60 | 61 | :: 62 | 63 | source /bin/activate 64 | (myenv) $ pip install tox 65 | (myenv) $ tox 66 | 67 | Credits 68 | ------- 69 | 70 | Tools used in rendering this package: 71 | 72 | * Cookiecutter_ 73 | * `cookiecutter-djangopackage`_ 74 | 75 | .. _Cookiecutter: https://github.com/audreyr/cookiecutter 76 | .. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage 77 | -------------------------------------------------------------------------------- /django_jsonschema_widget/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.1.0' 2 | -------------------------------------------------------------------------------- /django_jsonschema_widget/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 2 | from django.apps import AppConfig 3 | 4 | 5 | class JsonschemaWidgetConfig(AppConfig): 6 | name = 'django_jsonschema_widget' 7 | -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/css/jsonschema_widget.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openwisp/django-jsonschema-widget/8a1a86eceac96645fd855adf2f6a7f2cf89ff17e/django_jsonschema_widget/static/django-jsonschema-widget/css/jsonschema_widget.css -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/css/lib/advanced-mode.css: -------------------------------------------------------------------------------- 1 | /* reset styling (prevent conflicts with bootstrap, materialize.css, etc.) */ 2 | 3 | .field-config div.jsoneditor .jsoneditor-search input { 4 | height: auto; 5 | border: inherit; 6 | } 7 | 8 | .field-config div.jsoneditor .jsoneditor-search input:focus { 9 | border: none !important; 10 | box-shadow: none !important; 11 | } 12 | 13 | .field-config div.jsoneditor table { 14 | border-collapse: collapse; 15 | width: auto; 16 | } 17 | 18 | .field-config div.jsoneditor td, 19 | .field-config div.jsoneditor th { 20 | padding: 0; 21 | display: table-cell; 22 | text-align: left; 23 | vertical-align: inherit; 24 | border-radius: inherit; 25 | } 26 | 27 | 28 | div.jsoneditor-field, 29 | div.jsoneditor-value, 30 | div.jsoneditor-readonly { 31 | border: 1px solid transparent; 32 | min-height: 16px; 33 | min-width: 32px; 34 | padding: 2px; 35 | margin: 1px; 36 | word-wrap: break-word; 37 | float: left; 38 | } 39 | 40 | /* adjust margin of p elements inside editable divs, needed for Opera, IE */ 41 | 42 | div.jsoneditor-field p, 43 | div.jsoneditor-value p { 44 | margin: 0; 45 | } 46 | 47 | div.jsoneditor-value { 48 | word-break: break-word; 49 | } 50 | 51 | div.jsoneditor-readonly { 52 | min-width: 16px; 53 | color: gray; 54 | } 55 | 56 | div.jsoneditor-empty { 57 | border-color: lightgray; 58 | border-style: dashed; 59 | border-radius: 2px; 60 | } 61 | 62 | div.jsoneditor-field.jsoneditor-empty::after, 63 | div.jsoneditor-value.jsoneditor-empty::after { 64 | pointer-events: none; 65 | color: lightgray; 66 | font-size: 8pt; 67 | } 68 | 69 | div.jsoneditor-field.jsoneditor-empty::after { 70 | content: "field"; 71 | } 72 | 73 | div.jsoneditor-value.jsoneditor-empty::after { 74 | content: "value"; 75 | } 76 | 77 | div.jsoneditor-value.jsoneditor-url, 78 | a.jsoneditor-value.jsoneditor-url { 79 | color: green; 80 | text-decoration: underline; 81 | } 82 | 83 | a.jsoneditor-value.jsoneditor-url { 84 | display: inline-block; 85 | padding: 2px; 86 | margin: 2px; 87 | } 88 | 89 | a.jsoneditor-value.jsoneditor-url:hover, 90 | a.jsoneditor-value.jsoneditor-url:focus { 91 | color: #ee422e; 92 | } 93 | 94 | .field-config div.jsoneditor td.jsoneditor-separator { 95 | padding: 3px 0; 96 | vertical-align: top; 97 | color: gray; 98 | } 99 | 100 | div.jsoneditor-field[contenteditable=true]:focus, 101 | div.jsoneditor-field[contenteditable=true]:hover, 102 | div.jsoneditor-value[contenteditable=true]:focus, 103 | div.jsoneditor-value[contenteditable=true]:hover, 104 | div.jsoneditor-field.jsoneditor-highlight, 105 | div.jsoneditor-value.jsoneditor-highlight { 106 | background-color: #FFFFAB; 107 | border: 1px solid yellow; 108 | border-radius: 2px; 109 | } 110 | 111 | div.jsoneditor-field.jsoneditor-highlight-active, 112 | div.jsoneditor-field.jsoneditor-highlight-active:focus, 113 | div.jsoneditor-field.jsoneditor-highlight-active:hover, 114 | div.jsoneditor-value.jsoneditor-highlight-active, 115 | div.jsoneditor-value.jsoneditor-highlight-active:focus, 116 | div.jsoneditor-value.jsoneditor-highlight-active:hover { 117 | background-color: #ffee00; 118 | border: 1px solid #ffc700; 119 | border-radius: 2px; 120 | } 121 | 122 | div.jsoneditor-value.jsoneditor-string { 123 | color: #008000; 124 | } 125 | 126 | div.jsoneditor-value.jsoneditor-object, 127 | div.jsoneditor-value.jsoneditor-array { 128 | min-width: 16px; 129 | color: #808080; 130 | } 131 | 132 | div.jsoneditor-value.jsoneditor-number { 133 | color: #ee422e; 134 | } 135 | 136 | div.jsoneditor-value.jsoneditor-boolean { 137 | color: #ff8c00; 138 | } 139 | 140 | div.jsoneditor-value.jsoneditor-null { 141 | color: #004ED0; 142 | } 143 | 144 | div.jsoneditor-value.jsoneditor-invalid { 145 | color: #000000; 146 | } 147 | 148 | div.jsoneditor-tree button { 149 | width: 24px; 150 | height: 24px; 151 | padding: 0; 152 | margin: 0; 153 | border: none; 154 | cursor: pointer; 155 | background: transparent url("img/jsoneditor-icons.svg"); 156 | } 157 | 158 | div.jsoneditor-mode-view tr.jsoneditor-expandable td.jsoneditor-tree, 159 | div.jsoneditor-mode-form tr.jsoneditor-expandable td.jsoneditor-tree { 160 | cursor: pointer; 161 | } 162 | 163 | div.jsoneditor-tree button.jsoneditor-collapsed { 164 | background-position: 0 -48px; 165 | } 166 | 167 | div.jsoneditor-tree button.jsoneditor-expanded { 168 | background-position: 0 -72px; 169 | } 170 | 171 | div.jsoneditor-tree button.jsoneditor-contextmenu { 172 | background-position: -48px -72px; 173 | } 174 | 175 | div.jsoneditor-tree button.jsoneditor-contextmenu:hover, 176 | div.jsoneditor-tree button.jsoneditor-contextmenu:focus, 177 | div.jsoneditor-tree button.jsoneditor-contextmenu.jsoneditor-selected, 178 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu { 179 | background-position: -48px -48px; 180 | } 181 | 182 | div.jsoneditor-tree *:focus { 183 | outline: none; 184 | } 185 | 186 | div.jsoneditor-tree button:focus { 187 | /* TODO: nice outline for buttons with focus 188 | outline: #97B0F8 solid 2px; 189 | box-shadow: 0 0 8px #97B0F8; 190 | */ 191 | background-color: #f5f5f5; 192 | outline: #e5e5e5 solid 1px; 193 | } 194 | 195 | div.jsoneditor-tree button.jsoneditor-invisible { 196 | visibility: hidden; 197 | background: none; 198 | } 199 | 200 | .field-config div.jsoneditor { 201 | color: #1A1A1A; 202 | border: 1px solid #3883fa; 203 | -moz-box-sizing: border-box; 204 | -webkit-box-sizing: border-box; 205 | box-sizing: border-box; 206 | width: 100%; 207 | height: 100%; 208 | overflow: hidden; 209 | position: relative; 210 | padding: 0; 211 | line-height: 100%; 212 | } 213 | 214 | div.jsoneditor-tree table.jsoneditor-tree { 215 | border-collapse: collapse; 216 | border-spacing: 0; 217 | width: 100%; 218 | margin: 0; 219 | } 220 | 221 | div.jsoneditor-outer { 222 | position: static; 223 | width: 100%; 224 | height: 100%; 225 | margin: -35px 0 0 0; 226 | padding: 35px 0 0 0; 227 | -moz-box-sizing: border-box; 228 | -webkit-box-sizing: border-box; 229 | box-sizing: border-box; 230 | } 231 | 232 | textarea.jsoneditor-text, 233 | .ace_editor { 234 | min-height: 550px; 235 | } 236 | 237 | div.jsoneditor-tree { 238 | width: 100%; 239 | height: 100%; 240 | position: relative; 241 | overflow: auto; 242 | min-height: 320px; 243 | } 244 | 245 | textarea.jsoneditor-text { 246 | width: 100%; 247 | height: 100%; 248 | margin: 0; 249 | -moz-box-sizing: border-box; 250 | -webkit-box-sizing: border-box; 251 | box-sizing: border-box; 252 | outline-width: 0; 253 | border: none; 254 | background-color: white; 255 | resize: none; 256 | } 257 | 258 | tr.jsoneditor-highlight, 259 | tr.jsoneditor-selected { 260 | background-color: #e6e6e6; 261 | } 262 | 263 | tr.jsoneditor-selected button.jsoneditor-dragarea, 264 | tr.jsoneditor-selected button.jsoneditor-contextmenu { 265 | visibility: hidden; 266 | } 267 | 268 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea, 269 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu { 270 | visibility: visible; 271 | } 272 | 273 | div.jsoneditor-tree button.jsoneditor-dragarea { 274 | background: url("img/jsoneditor-icons.svg") -72px -72px; 275 | cursor: move; 276 | } 277 | 278 | div.jsoneditor-tree button.jsoneditor-dragarea:hover, 279 | div.jsoneditor-tree button.jsoneditor-dragarea:focus, 280 | tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea { 281 | background-position: -72px -48px; 282 | } 283 | 284 | .field-config div.jsoneditor tr, 285 | .field-config div.jsoneditor th, 286 | .field-config div.jsoneditor td { 287 | padding: 0; 288 | margin: 0; 289 | } 290 | 291 | .field-config div.jsoneditor td { 292 | vertical-align: top; 293 | } 294 | 295 | .field-config div.jsoneditor td.jsoneditor-tree { 296 | vertical-align: top; 297 | } 298 | 299 | div.jsoneditor-field, 300 | div.jsoneditor-value, 301 | .field-config div.jsoneditor td, 302 | .field-config div.jsoneditor th, 303 | .field-config div.jsoneditor textarea, 304 | .jsoneditor-schema-error { 305 | font-family: droid sans mono, consolas, monospace, courier new, courier, sans-serif; 306 | font-size: 10pt; 307 | color: #1A1A1A; 308 | } 309 | 310 | /* popover */ 311 | 312 | .jsoneditor-schema-error { 313 | cursor: default; 314 | display: inline-block; 315 | /*font-family: arial, sans-serif;*/ 316 | height: 24px; 317 | line-height: 24px; 318 | position: relative; 319 | text-align: center; 320 | width: 24px; 321 | } 322 | 323 | div.jsoneditor-tree .jsoneditor-schema-error { 324 | width: 24px; 325 | height: 24px; 326 | padding: 0; 327 | margin: 0 4px 0 0; 328 | background: url("img/jsoneditor-icons.svg") -168px -48px; 329 | } 330 | 331 | .jsoneditor-schema-error .jsoneditor-popover { 332 | background-color: #4c4c4c; 333 | border-radius: 3px; 334 | box-shadow: 0 0 5px rgba(0,0,0,0.4); 335 | color: #fff; 336 | display: none; 337 | padding: 7px 10px; 338 | position: absolute; 339 | width: 200px; 340 | z-index: 4; 341 | } 342 | 343 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-above { 344 | bottom: 32px; 345 | left: -98px; 346 | } 347 | 348 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-below { 349 | top: 32px; 350 | left: -98px; 351 | } 352 | 353 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-left { 354 | top: -7px; 355 | right: 32px; 356 | } 357 | 358 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-right { 359 | top: -7px; 360 | left: 32px; 361 | } 362 | 363 | .jsoneditor-schema-error .jsoneditor-popover:before { 364 | border-right: 7px solid transparent; 365 | border-left: 7px solid transparent; 366 | content: ''; 367 | display: block; 368 | left: 50%; 369 | margin-left: -7px; 370 | position: absolute; 371 | } 372 | 373 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-above:before { 374 | border-top: 7px solid #4c4c4c; 375 | bottom: -7px; 376 | } 377 | 378 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-below:before { 379 | border-bottom: 7px solid #4c4c4c; 380 | top: -7px; 381 | } 382 | 383 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-left:before { 384 | border-left: 7px solid #4c4c4c; 385 | border-top: 7px solid transparent; 386 | border-bottom: 7px solid transparent; 387 | content: ''; 388 | top: 19px; 389 | right: -14px; 390 | left: inherit; 391 | margin-left: inherit; 392 | margin-top: -7px; 393 | position: absolute; 394 | } 395 | 396 | .jsoneditor-schema-error .jsoneditor-popover.jsoneditor-right:before { 397 | border-right: 7px solid #4c4c4c; 398 | border-top: 7px solid transparent; 399 | border-bottom: 7px solid transparent; 400 | content: ''; 401 | top: 19px; 402 | left: -14px; 403 | margin-left: inherit; 404 | margin-top: -7px; 405 | position: absolute; 406 | } 407 | 408 | .jsoneditor-schema-error:hover .jsoneditor-popover, 409 | .jsoneditor-schema-error:focus .jsoneditor-popover { 410 | display: block; 411 | -webkit-animation: fade-in .3s linear 1, move-up .3s linear 1; 412 | -moz-animation: fade-in .3s linear 1, move-up .3s linear 1; 413 | -ms-animation: fade-in .3s linear 1, move-up .3s linear 1; 414 | } 415 | 416 | @-webkit-keyframes fade-in { 417 | from { 418 | opacity: 0; 419 | } 420 | 421 | to { 422 | opacity: 1; 423 | } 424 | } 425 | 426 | @-moz-keyframes fade-in { 427 | from { 428 | opacity: 0; 429 | } 430 | 431 | to { 432 | opacity: 1; 433 | } 434 | } 435 | 436 | @-ms-keyframes fade-in { 437 | from { 438 | opacity: 0; 439 | } 440 | 441 | to { 442 | opacity: 1; 443 | } 444 | } 445 | 446 | /*@-webkit-keyframes move-up {*/ 447 | 448 | /*from { bottom: 24px; }*/ 449 | 450 | /*to { bottom: 32px; }*/ 451 | 452 | /*}*/ 453 | 454 | /*@-moz-keyframes move-up {*/ 455 | 456 | /*from { bottom: 24px; }*/ 457 | 458 | /*to { bottom: 32px; }*/ 459 | 460 | /*}*/ 461 | 462 | /*@-ms-keyframes move-up {*/ 463 | 464 | /*from { bottom: 24px; }*/ 465 | 466 | /*to { bottom: 32px; }*/ 467 | 468 | /*}*/ 469 | 470 | /* JSON schema errors displayed at the bottom of the editor in mode text and code */ 471 | 472 | .jsoneditor .jsoneditor-text-errors { 473 | width: 100%; 474 | border-collapse: collapse; 475 | background-color: #ffef8b; 476 | border-top: 1px solid #ffd700; 477 | } 478 | 479 | .jsoneditor .jsoneditor-text-errors td { 480 | padding: 3px 6px; 481 | vertical-align: middle; 482 | } 483 | 484 | .jsoneditor-text-errors .jsoneditor-schema-error { 485 | border: none; 486 | width: 24px; 487 | height: 24px; 488 | padding: 0; 489 | margin: 0 4px 0 0; 490 | background: url("img/jsoneditor-icons.svg") -168px -48px; 491 | } 492 | /* ContextMenu - main menu */ 493 | 494 | div.jsoneditor-contextmenu-root { 495 | position: relative; 496 | width: 0; 497 | height: 0; 498 | } 499 | 500 | div.jsoneditor-contextmenu { 501 | position: absolute; 502 | box-sizing: content-box; 503 | z-index: 99999; 504 | } 505 | 506 | div.jsoneditor-contextmenu ul, 507 | div.jsoneditor-contextmenu li { 508 | box-sizing: content-box; 509 | } 510 | 511 | div.jsoneditor-contextmenu ul { 512 | position: relative; 513 | left: 0; 514 | top: 0; 515 | width: 124px; 516 | background: white; 517 | border: 1px solid #d3d3d3; 518 | box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); 519 | list-style: none; 520 | margin: 0; 521 | padding: 0; 522 | } 523 | 524 | div.jsoneditor-contextmenu ul li button { 525 | padding: 0; 526 | margin: 0; 527 | width: 124px; 528 | height: 24px; 529 | border: none; 530 | cursor: pointer; 531 | color: #4d4d4d; 532 | background: transparent; 533 | font-size: 10pt; 534 | font-family: arial, sans-serif; 535 | box-sizing: border-box; 536 | line-height: 26px; 537 | text-align: left; 538 | } 539 | 540 | /* Fix button padding in firefox */ 541 | 542 | div.jsoneditor-contextmenu ul li button::-moz-focus-inner { 543 | padding: 0; 544 | border: 0; 545 | } 546 | 547 | div.jsoneditor-contextmenu ul li button:hover, 548 | div.jsoneditor-contextmenu ul li button:focus { 549 | color: #1a1a1a; 550 | background-color: #f5f5f5; 551 | outline: none; 552 | } 553 | 554 | div.jsoneditor-contextmenu ul li button.jsoneditor-default { 555 | width: 92px; 556 | } 557 | 558 | div.jsoneditor-contextmenu ul li button.jsoneditor-expand { 559 | float: right; 560 | width: 32px; 561 | height: 24px; 562 | border-left: 1px solid #e5e5e5; 563 | } 564 | 565 | div.jsoneditor-contextmenu div.jsoneditor-icon { 566 | float: left; 567 | width: 24px; 568 | height: 24px; 569 | border: none; 570 | padding: 0; 571 | margin: 0; 572 | background-image: url("img/jsoneditor-icons.svg"); 573 | } 574 | 575 | div.jsoneditor-contextmenu ul li button div.jsoneditor-expand { 576 | float: right; 577 | width: 24px; 578 | height: 24px; 579 | padding: 0; 580 | margin: 0 4px 0 0; 581 | background: url("img/jsoneditor-icons.svg") 0 -72px; 582 | opacity: 0.4; 583 | } 584 | 585 | div.jsoneditor-contextmenu ul li button:hover div.jsoneditor-expand, 586 | div.jsoneditor-contextmenu ul li button:focus div.jsoneditor-expand, 587 | div.jsoneditor-contextmenu ul li.jsoneditor-selected div.jsoneditor-expand, 588 | div.jsoneditor-contextmenu ul li button.jsoneditor-expand:hover div.jsoneditor-expand, 589 | div.jsoneditor-contextmenu ul li button.jsoneditor-expand:focus div.jsoneditor-expand { 590 | opacity: 1; 591 | } 592 | 593 | div.jsoneditor-contextmenu div.jsoneditor-separator { 594 | height: 0; 595 | border-top: 1px solid #e5e5e5; 596 | padding-top: 5px; 597 | margin-top: 5px; 598 | } 599 | 600 | div.jsoneditor-contextmenu button.jsoneditor-remove > div.jsoneditor-icon { 601 | background-position: -24px -24px; 602 | } 603 | 604 | div.jsoneditor-contextmenu button.jsoneditor-remove:hover > div.jsoneditor-icon, 605 | div.jsoneditor-contextmenu button.jsoneditor-remove:focus > div.jsoneditor-icon { 606 | background-position: -24px 0; 607 | } 608 | 609 | div.jsoneditor-contextmenu button.jsoneditor-append > div.jsoneditor-icon { 610 | background-position: 0 -24px; 611 | } 612 | 613 | div.jsoneditor-contextmenu button.jsoneditor-append:hover > div.jsoneditor-icon, 614 | div.jsoneditor-contextmenu button.jsoneditor-append:focus > div.jsoneditor-icon { 615 | background-position: 0 0; 616 | } 617 | 618 | div.jsoneditor-contextmenu button.jsoneditor-insert > div.jsoneditor-icon { 619 | background-position: 0 -24px; 620 | } 621 | 622 | div.jsoneditor-contextmenu button.jsoneditor-insert:hover > div.jsoneditor-icon, 623 | div.jsoneditor-contextmenu button.jsoneditor-insert:focus > div.jsoneditor-icon { 624 | background-position: 0 0; 625 | } 626 | 627 | div.jsoneditor-contextmenu button.jsoneditor-duplicate > div.jsoneditor-icon { 628 | background-position: -48px -24px; 629 | } 630 | 631 | div.jsoneditor-contextmenu button.jsoneditor-duplicate:hover > div.jsoneditor-icon, 632 | div.jsoneditor-contextmenu button.jsoneditor-duplicate:focus > div.jsoneditor-icon { 633 | background-position: -48px 0; 634 | } 635 | 636 | div.jsoneditor-contextmenu button.jsoneditor-sort-asc > div.jsoneditor-icon { 637 | background-position: -168px -24px; 638 | } 639 | 640 | div.jsoneditor-contextmenu button.jsoneditor-sort-asc:hover > div.jsoneditor-icon, 641 | div.jsoneditor-contextmenu button.jsoneditor-sort-asc:focus > div.jsoneditor-icon { 642 | background-position: -168px 0; 643 | } 644 | 645 | div.jsoneditor-contextmenu button.jsoneditor-sort-desc > div.jsoneditor-icon { 646 | background-position: -192px -24px; 647 | } 648 | 649 | div.jsoneditor-contextmenu button.jsoneditor-sort-desc:hover > div.jsoneditor-icon, 650 | div.jsoneditor-contextmenu button.jsoneditor-sort-desc:focus > div.jsoneditor-icon { 651 | background-position: -192px 0; 652 | } 653 | 654 | /* ContextMenu - sub menu */ 655 | 656 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected, 657 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected:hover, 658 | div.jsoneditor-contextmenu ul li button.jsoneditor-selected:focus { 659 | color: white; 660 | background-color: #ee422e; 661 | } 662 | 663 | div.jsoneditor-contextmenu ul li { 664 | overflow: hidden; 665 | } 666 | 667 | div.jsoneditor-contextmenu ul li ul { 668 | display: none; 669 | position: relative; 670 | left: -10px; 671 | top: 0; 672 | border: none; 673 | box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5); 674 | padding: 0 10px; 675 | /* TODO: transition is not supported on IE8-9 */ 676 | -webkit-transition: all 0.3s ease-out; 677 | -moz-transition: all 0.3s ease-out; 678 | -o-transition: all 0.3s ease-out; 679 | transition: all 0.3s ease-out; 680 | } 681 | 682 | 683 | 684 | div.jsoneditor-contextmenu ul li ul li button { 685 | padding-left: 24px; 686 | animation: all ease-in-out 1s; 687 | } 688 | 689 | div.jsoneditor-contextmenu ul li ul li button:hover, 690 | div.jsoneditor-contextmenu ul li ul li button:focus { 691 | background-color: #f5f5f5; 692 | } 693 | 694 | div.jsoneditor-contextmenu button.jsoneditor-type-string > div.jsoneditor-icon { 695 | background-position: -144px -24px; 696 | } 697 | 698 | div.jsoneditor-contextmenu button.jsoneditor-type-string:hover > div.jsoneditor-icon, 699 | div.jsoneditor-contextmenu button.jsoneditor-type-string:focus > div.jsoneditor-icon, 700 | div.jsoneditor-contextmenu button.jsoneditor-type-string.jsoneditor-selected > div.jsoneditor-icon { 701 | background-position: -144px 0; 702 | } 703 | 704 | div.jsoneditor-contextmenu button.jsoneditor-type-auto > div.jsoneditor-icon { 705 | background-position: -120px -24px; 706 | } 707 | 708 | div.jsoneditor-contextmenu button.jsoneditor-type-auto:hover > div.jsoneditor-icon, 709 | div.jsoneditor-contextmenu button.jsoneditor-type-auto:focus > div.jsoneditor-icon, 710 | div.jsoneditor-contextmenu button.jsoneditor-type-auto.jsoneditor-selected > div.jsoneditor-icon { 711 | background-position: -120px 0; 712 | } 713 | 714 | div.jsoneditor-contextmenu button.jsoneditor-type-object > div.jsoneditor-icon { 715 | background-position: -72px -24px; 716 | } 717 | 718 | div.jsoneditor-contextmenu button.jsoneditor-type-object:hover > div.jsoneditor-icon, 719 | div.jsoneditor-contextmenu button.jsoneditor-type-object:focus > div.jsoneditor-icon, 720 | div.jsoneditor-contextmenu button.jsoneditor-type-object.jsoneditor-selected > div.jsoneditor-icon { 721 | background-position: -72px 0; 722 | } 723 | 724 | div.jsoneditor-contextmenu button.jsoneditor-type-array > div.jsoneditor-icon { 725 | background-position: -96px -24px; 726 | } 727 | 728 | div.jsoneditor-contextmenu button.jsoneditor-type-array:hover > div.jsoneditor-icon, 729 | div.jsoneditor-contextmenu button.jsoneditor-type-array:focus > div.jsoneditor-icon, 730 | div.jsoneditor-contextmenu button.jsoneditor-type-array.jsoneditor-selected > div.jsoneditor-icon { 731 | background-position: -96px 0; 732 | } 733 | 734 | div.jsoneditor-contextmenu button.jsoneditor-type-modes > div.jsoneditor-icon { 735 | background-image: none; 736 | width: 6px; 737 | } 738 | div.jsoneditor-menu { 739 | width: 100%; 740 | height: 35px; 741 | padding: 2px; 742 | margin: 0; 743 | -moz-box-sizing: border-box; 744 | -webkit-box-sizing: border-box; 745 | box-sizing: border-box; 746 | color: white; 747 | background-color: #3883fa; 748 | border-bottom: 1px solid #3883fa; 749 | } 750 | 751 | div.jsoneditor-menu > button, 752 | div.jsoneditor-menu > div.jsoneditor-modes > button { 753 | width: 26px; 754 | height: 26px; 755 | margin: 2px; 756 | padding: 0; 757 | border-radius: 2px; 758 | border: 1px solid transparent; 759 | background: transparent url("img/jsoneditor-icons.svg"); 760 | color: white; 761 | opacity: 0.8; 762 | font-family: arial, sans-serif; 763 | font-size: 10pt; 764 | float: left; 765 | } 766 | 767 | div.jsoneditor-menu > button:hover, 768 | div.jsoneditor-menu > div.jsoneditor-modes > button:hover { 769 | background-color: rgba(255,255,255,0.2); 770 | border: 1px solid rgba(255,255,255,0.4); 771 | } 772 | 773 | div.jsoneditor-menu > button:focus, 774 | div.jsoneditor-menu > button:active, 775 | div.jsoneditor-menu > div.jsoneditor-modes > button:focus, 776 | div.jsoneditor-menu > div.jsoneditor-modes > button:active { 777 | background-color: rgba(255,255,255,0.3); 778 | } 779 | 780 | div.jsoneditor-menu > button:disabled, 781 | div.jsoneditor-menu > div.jsoneditor-modes > button:disabled { 782 | opacity: 0.5; 783 | } 784 | 785 | div.jsoneditor-menu > button.jsoneditor-collapse-all { 786 | background-position: 0 -96px; 787 | } 788 | 789 | div.jsoneditor-menu > button.jsoneditor-expand-all { 790 | background-position: 0 -120px; 791 | } 792 | 793 | div.jsoneditor-menu > button.jsoneditor-undo { 794 | background-position: -24px -96px; 795 | } 796 | 797 | div.jsoneditor-menu > button.jsoneditor-undo:disabled { 798 | background-position: -24px -120px; 799 | } 800 | 801 | div.jsoneditor-menu > button.jsoneditor-redo { 802 | background-position: -48px -96px; 803 | } 804 | 805 | div.jsoneditor-menu > button.jsoneditor-redo:disabled { 806 | background-position: -48px -120px; 807 | } 808 | 809 | div.jsoneditor-menu > button.jsoneditor-compact { 810 | background-position: -72px -96px; 811 | } 812 | 813 | div.jsoneditor-menu > button.jsoneditor-format { 814 | background-position: -72px -120px; 815 | } 816 | 817 | div.jsoneditor-menu > div.jsoneditor-modes { 818 | display: inline-block; 819 | float: left; 820 | } 821 | 822 | div.jsoneditor-menu > div.jsoneditor-modes > button { 823 | background-image: none; 824 | width: auto; 825 | padding-left: 6px; 826 | padding-right: 6px; 827 | } 828 | 829 | div.jsoneditor-menu > button.jsoneditor-separator, 830 | div.jsoneditor-menu > div.jsoneditor-modes > button.jsoneditor-separator { 831 | margin-left: 10px; 832 | } 833 | 834 | div.jsoneditor-menu a { 835 | font-family: arial, sans-serif; 836 | font-size: 10pt; 837 | color: white; 838 | opacity: 0.8; 839 | vertical-align: middle; 840 | } 841 | 842 | div.jsoneditor-menu a:hover { 843 | opacity: 1; 844 | } 845 | 846 | div.jsoneditor-menu a.jsoneditor-exit { 847 | font-size: 8pt; 848 | position: absolute; 849 | right: 0; 850 | top: 0; 851 | padding: 10px; 852 | font-size: 13px; 853 | background-color: #fff; 854 | color: #000; 855 | margin-bottom: 1px; 856 | } 857 | div.jsoneditor-menu a.jsoneditor-exit img{ margin: -2px 1px 0 0 } 858 | table.jsoneditor-search input, 859 | table.jsoneditor-search div.jsoneditor-results { 860 | font-family: arial, sans-serif; 861 | font-size: 10pt; 862 | color: #1A1A1A; 863 | background: transparent; 864 | /* For Firefox */ 865 | } 866 | 867 | table.jsoneditor-search div.jsoneditor-results { 868 | color: white; 869 | padding-right: 5px; 870 | line-height: 24px; 871 | } 872 | 873 | table.jsoneditor-search { 874 | position: absolute; 875 | right: 4px; 876 | top: 4px; 877 | border-collapse: collapse; 878 | border-spacing: 0; 879 | } 880 | 881 | table.jsoneditor-search div.jsoneditor-frame { 882 | border: 1px solid transparent; 883 | background-color: white; 884 | padding: 0 2px; 885 | margin: 0; 886 | } 887 | 888 | table.jsoneditor-search div.jsoneditor-frame table { 889 | border-collapse: collapse; 890 | } 891 | 892 | table.jsoneditor-search input { 893 | width: 120px; 894 | border: none; 895 | outline: none; 896 | margin: 1px; 897 | line-height: 20px; 898 | } 899 | 900 | table.jsoneditor-search button { 901 | width: 16px; 902 | height: 24px; 903 | padding: 0; 904 | margin: 0; 905 | border: none; 906 | background: url("img/jsoneditor-icons.svg"); 907 | vertical-align: top; 908 | } 909 | 910 | table.jsoneditor-search button:hover { 911 | background-color: transparent; 912 | } 913 | 914 | table.jsoneditor-search button.jsoneditor-refresh { 915 | width: 18px; 916 | background-position: -99px -73px; 917 | } 918 | 919 | table.jsoneditor-search button.jsoneditor-next { 920 | cursor: pointer; 921 | background-position: -124px -73px; 922 | } 923 | 924 | table.jsoneditor-search button.jsoneditor-next:hover { 925 | background-position: -124px -49px; 926 | } 927 | 928 | table.jsoneditor-search button.jsoneditor-previous { 929 | cursor: pointer; 930 | background-position: -148px -73px; 931 | margin-right: 2px; 932 | } 933 | 934 | table.jsoneditor-search button.jsoneditor-previous:hover { 935 | background-position: -148px -49px; 936 | } 937 | 938 | .field-config div.jsoneditor{ 939 | min-height: 300px !important; 940 | } 941 | 942 | .jsoneditor-text-errors{ width: 100% !important } 943 | .jsoneditor-text-errors td:first-child{ padding-left: 15px !important } 944 | .jsoneditor-text-errors td:last-child{ padding-right: 15px !important } 945 | .jsoneditor-text-errors td{ vertical-align: middle !important } 946 | .jsoneditor-text-errors td button { 947 | vertical-align: bottom !important; 948 | margin-top: 1px !important; 949 | } 950 | .jsoneditor-text-errors td pre{ margin: 0 } 951 | 952 | .full-screen{ 953 | position: absolute; 954 | top: 0px; 955 | left: 0px; 956 | padding-left: 0px; 957 | padding-right: 0px; 958 | background-color: #ffffff; 959 | width: 100%; 960 | z-index: 9; 961 | } 962 | 963 | .editor-full{ 964 | overflow: hidden; 965 | } 966 | 967 | .field-config .screen-mode{ 968 | float: right; 969 | } 970 | 971 | .jsoneditor-menu label{ 972 | margin-left: 10px; 973 | color: #fff !important; 974 | line-height: 28px; 975 | padding: 0; 976 | margin-left: 20px; 977 | } 978 | 979 | .jsoneditor-menu label a{ 980 | font-weight: bold; 981 | color: #fff !important; 982 | } 983 | -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/css/lib/img/jsoneditor-icons.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | JSON Editor Icons 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | JSON Editor Icons 27 | 28 | 29 | 30 | 32 | 56 | 60 | 61 | 62 | 64 | 71 | 78 | 85 | 92 | 99 | 102 | 109 | 116 | 117 | 121 | 128 | 135 | 136 | 143 | 150 | 157 | 159 | 166 | 173 | 180 | 181 | 184 | 191 | 198 | 205 | 206 | 213 | 219 | 225 | 232 | 237 | 242 | 249 | 255 | 260 | 267 | 273 | 279 | 280 | 287 | 294 | 301 | 308 | 315 | 319 | 326 | 333 | 334 | 338 | 345 | 352 | 353 | 360 | 367 | 374 | 377 | 384 | 391 | 398 | 399 | 402 | 409 | 416 | 423 | 424 | 431 | 437 | 443 | 450 | 455 | 460 | 467 | 473 | 478 | 485 | 491 | 497 | 504 | 511 | 518 | 525 | 532 | 539 | 546 | 552 | 560 | 566 | 572 | 579 | 587 | 595 | 602 | 609 | 616 | 623 | 630 | 637 | 644 | 651 | 657 | 665 | 671 | 677 | 684 | 692 | 700 | 707 | 714 | 721 | 728 | 735 | 742 | 749 | 756 | 761 | 766 | 771 | 777 | 783 | 788 | 793 | 798 | 803 | 808 | 824 | 841 | 858 | 875 | 881 | 887 | 893 | 894 | -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/css/lib/jsonschema-ui.css: -------------------------------------------------------------------------------- 1 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group{ margin-top: 15px } 2 | .jsoneditor-wrapper div.jsoneditor .grid-row:first-child > .inline-group{ margin-top: 0 } 3 | .form-row.field-config{ display: none } 4 | .form-row.field-config .advanced-mode{ display: none } 5 | .jsoneditor-wrapper div.jsoneditor-wrapper > fieldset{ 6 | margin-bottom: 0; 7 | border-bottom: 1px solid #eee; 8 | } 9 | .jsoneditor-wrapper div.jsoneditor-wrapper h2{ padding: 18px } 10 | input.deletelink{ background: #ba2121 } 11 | input.deletelink:hover, 12 | input.deletelink:focus{ background: #a41515 } 13 | .jsoneditor-wrapper div.jsoneditor input.button, 14 | .jsoneditor-wrapper div.jsoneditor input.deletelink, 15 | .form-row .json-editor-btn-edit{ 16 | margin-left: 10px; 17 | padding: 6px 12px; 18 | } 19 | a.json-editor-btn-edit{ 20 | margin-left: 10px; 21 | padding: 6px 12px; 22 | color: #ffffff; 23 | } 24 | 25 | .form-row .json-editor-btn-edit{ margin-bottom: 10px !important } 26 | .jsoneditor-wrapper div.jsoneditor .form-row{ padding: 15px 15px 15px 0 } 27 | .jsoneditor-wrapper div.jsoneditor label{ margin-left: 20px } 28 | .jsoneditor-wrapper div.jsoneditor .form-row:last-child{ border-bottom-width: 0 } 29 | .jsoneditor-wrapper div.jsoneditor .inline-group{ 30 | clear: both; 31 | margin: 0; 32 | border: 1px solid #eee; 33 | } 34 | 35 | /* avoid redundant borders */ 36 | .jsoneditor-wrapper div.jsoneditor .inline-group > .inline-related > .grid-container > div > .grid-row > .grid-column > div > .inline-group, 37 | .jsoneditor-wrapper div.jsoneditor .inline-group > .inline-related > .grid-container > div > .inline-group{ 38 | border: 0 none; 39 | } 40 | 41 | /* advanced mode and object properties */ 42 | .jsoneditor-wrapper div.jsoneditor > div > h3.controls{ 43 | padding: 12px 0; 44 | margin: 0; 45 | } 46 | .jsoneditor-wrapper div.jsoneditor > div > h3.controls .button{ margin: 0 13px } 47 | 48 | .jsoneditor-wrapper div.jsoneditor div[data-schematype="array"] > .inline-related > div > .inline-related, 49 | .jsoneditor-wrapper div.jsoneditor div[data-schematype="array"] > .inline-related > div > .inline-group{ 50 | margin: 20px; 51 | } 52 | .jsoneditor-wrapper div.jsoneditor div[data-schematype="array"] > .inline-related > div > .inline-related:last-child, 53 | .jsoneditor-wrapper div.jsoneditor div[data-schematype="array"] > .inline-related > div > .inline-group:last-child{ 54 | margin-bottom: 0 55 | } 56 | .jsoneditor-wrapper div.jsoneditor div[data-schematype="array"] > .inline-related > div > .inline-related[data-schematype="string"]{ 57 | margin: 0; 58 | } 59 | 60 | .jsoneditor-wrapper div.jsoneditor div[data-schemapath="root.interfaces"] > div > div > div { 61 | border-bottom: 2px dotted #ccc; 62 | } 63 | 64 | .jsoneditor-wrapper div.jsoneditor div.control{ margin: 15px 0 } 65 | .jsoneditor-wrapper div.jsoneditor h3{ 66 | height: 56px; 67 | line-height: 55px; 68 | padding: 0 12px 0 15px; 69 | overflow: hidden; 70 | } 71 | .jsoneditor-wrapper div.jsoneditor h3 span{ 72 | display: inline-block; 73 | margin-right: 15px; 74 | line-height: 0; 75 | } 76 | .jsoneditor-wrapper div.jsoneditor h3 span.control{ 77 | margin-top: 12px; 78 | float: right; 79 | } 80 | .jsoneditor-wrapper div.jsoneditor .grid-column > h3{ 81 | border: 0 none; 82 | outline: 1px solid #eee; 83 | } 84 | 85 | span.control input{ margin: 0 0 0 15px } 86 | .jsoneditor-wrapper div.jsoneditor span.control{ 87 | padding: 0; 88 | margin-right: 0; 89 | } 90 | 91 | .jsoneditor-wrapper div.jsoneditor div[data-schemapath="root.interfaces"] > div > div > div { 92 | border-bottom: 2px dotted #ccc; 93 | padding-bottom: 20px; 94 | margin-bottom: 22px !important; 95 | } 96 | .jsoneditor-wrapper div.jsoneditor div[data-schemapath="root.interfaces"] > div > div > div:last-child { 97 | margin-bottom: 0 !important; 98 | } 99 | 100 | .jsoneditor-wrapper div.jsoneditor div[data-schemapath="root.interfaces"] > div > div > div > .control{ 101 | margin-bottom: 0; 102 | } 103 | 104 | div[data-schematype="array"] > div > div > 105 | div[data-schematype="string"].inline-related .control{ 106 | margin: -49px 10px 0; 107 | float: right; 108 | clear: both; 109 | } 110 | div[data-schematype="array"] > div > div > 111 | div[data-schematype="string"].inline-related{ padding: 0 !important } 112 | 113 | /* hide empty divs */ 114 | .jsoneditor-wrapper div.jsoneditor div:empty{ display: none !important } 115 | 116 | /* begin custom properties adjustments */ 117 | .jsoneditor-wrapper div.jsoneditor .inline-group{ margin-bottom: 0 } 118 | .jsoneditor-wrapper div.jsoneditor .inline-group > label, 119 | .jsoneditor-wrapper div.jsoneditor .inline-group > select{ 120 | vertical-align: top; 121 | margin: 15px 0 10px 15px; 122 | } 123 | .jsoneditor-wrapper div.jsoneditor .inline-group > label{ 124 | font-style: italic; 125 | display: inline-block; 126 | clear: both; 127 | float: none; 128 | margin-left: 15px; 129 | margin-bottom: 0; 130 | } 131 | .inline-group[data-schematype="object"] > .inline-related > .grid-container > 132 | div > .grid-row > .inline-group > div > .inline-group{ 133 | border: 0 none !important; 134 | } 135 | div[data-schematype="object"] > .inline-related > .grid-container > 136 | div > .grid-row > .inline-group { 137 | border-bottom: 1px solid #eee; 138 | } 139 | 140 | .grid-row > .inline-group > div > .inline-group > div.form-row{ 141 | border: 0 none; 142 | padding: 0; 143 | margin: 0 0 15px 15px; 144 | } 145 | 146 | div[data-schematype="object"] > .inline-related > .grid-container > div > 147 | .grid-row > .inline-group > div > div{ 148 | border: 0 none; 149 | } 150 | 151 | .jsoneditor-wrapper div.jsoneditor > div > .inline-related > .grid-container > div > .grid-row > 152 | .inline-group > div { 153 | display: block; 154 | } 155 | 156 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > h3 span{ display: inline-block !important } 157 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > .inline-related > div > .inline-related > label, 158 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > .inline-related > div > .inline-related > select{ 159 | position: static; 160 | margin-bottom: 15px; 161 | margin-left: 0; 162 | } 163 | 164 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > .inline-related > div > .inline-related 165 | .grid-row > .inline-group{ 166 | border-top: 0 none; 167 | border-left: 0 none; 168 | border-right: 0 none; 169 | } 170 | 171 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > .inline-related > div > .inline-related 172 | .inline-group[data-schematype="array"] .inline-related > div > .inline-related > div > .inline-group .form-row{ 173 | margin-left: 15px; 174 | border: 0 none; 175 | } 176 | 177 | .jsoneditor-wrapper div.jsoneditor .grid-row > .inline-group > div > .inline-group > .inline-related > div > .inline-related 178 | .inline-group[data-schematype="array"] .inline-related > div > .inline-related .deletelink{ 179 | margin-left: 0; 180 | } 181 | /* end custom properties adjustments */ 182 | 183 | /* oneOf switcher */ 184 | .jsoneditor-wrapper div.jsoneditor .inline-related > label, 185 | .jsoneditor-wrapper div.jsoneditor .inline-related > select, 186 | .jsoneditor-wrapper div.jsoneditor .grid-column > label, 187 | .jsoneditor-wrapper div.jsoneditor .grid-column > select{ 188 | position: absolute; 189 | top: 14px; 190 | left: 0; 191 | z-index: 1; 192 | font-weight: bold; 193 | } 194 | .jsoneditor-wrapper div.jsoneditor .inline-related > select, 195 | .jsoneditor-wrapper div.jsoneditor .grid-column > select{ 196 | margin-left: 188px; 197 | background-color: #fff 198 | } 199 | .jsoneditor-wrapper div.jsoneditor .grid-row .grid-column{ position: relative } 200 | 201 | .jsoneditor-wrapper div.jsoneditor .modal{ 202 | position: absolute; 203 | z-index: 10; 204 | background-color: white; 205 | border: 1px solid #ddd; 206 | padding-bottom: 10px; 207 | width: 340px; 208 | margin-left: -215px; 209 | } 210 | /* header */ 211 | .jsoneditor-wrapper div.jsoneditor .advanced-mode{ margin-top: -4px !important } 212 | .normal-mode{ float: right } 213 | .jsoneditor-wrapper div.jsoneditor > div > h3.controls{ text-align: right } 214 | .jsoneditor-wrapper div.jsoneditor > div > h3.controls > .control{ float: left } 215 | /* configuration menu modal */ 216 | .jsoneditor-wrapper div.jsoneditor > div > h3.controls > .control > .modal{ 217 | margin-left: 0; 218 | width: auto; 219 | } 220 | .jsoneditor-wrapper div.jsoneditor .modal .vTextField[type=text], 221 | .jsoneditor-wrapper div.jsoneditor .modal .button{ 222 | margin-top: 12px !important; 223 | margin-bottom: 3px !important 224 | } 225 | 226 | .jsoneditor-wrapper div.jsoneditor input[type=checkbox]{ margin-right: 7px } 227 | .jsoneditor-wrapper div.jsoneditor textarea{ 228 | min-width: 75%; 229 | min-height: 330px 230 | } 231 | .jsoneditor-wrapper div.jsoneditor .modal textarea{ 232 | margin-bottom: 10px; 233 | min-width: 450px; 234 | } 235 | .jsoneditor-wrapper div.jsoneditor .modal label{ margin-left: 5px } 236 | .jsoneditor-wrapper div.jsoneditor .property-selector{ 237 | max-height: 240px !important; 238 | width: auto !important; 239 | } 240 | .jsoneditor-wrapper div.jsoneditor .property-selector{ 241 | padding: 10px !important; 242 | } 243 | .jsoneditor-wrapper div.jsoneditor .property-selector input{ 244 | margin: 0 8px 0 0 245 | } 246 | .jsoneditor-wrapper div.jsoneditor .property-selector .form-row{ 247 | padding: 2px 10px !important 248 | } 249 | 250 | .jsoneditor-wrapper div.jsoneditor .errorlist{ 251 | margin-top: 3px; 252 | margin-left: 181px; 253 | } 254 | 255 | .jsoneditor-wrapper div.jsoneditor div.form-row > .help{ 256 | margin-left: 181px; 257 | margin-top: 4px; 258 | font-size: 13px; 259 | color: #888; 260 | } 261 | 262 | .jsoneditor-wrapper div.jsoneditor .inline-group > .help, 263 | .jsoneditor-wrapper div.jsoneditor .grid-column > .help{ 264 | padding: 20px 15px 20px 18px; 265 | margin: 0; 266 | border-bottom: 1px solid #eee; 267 | font-size: 13px; 268 | } 269 | 270 | .jsoneditor-wrapper div.jsoneditor .modal label{ width: auto } 271 | 272 | .jsoneditor-wrapper div.jsoneditor div.grid-column[data-schematype="boolean"] label{ 273 | float: left; 274 | } 275 | .jsoneditor-wrapper div.jsoneditor div.grid-column[data-schematype="boolean"] .help{ 276 | float: left; 277 | clear: none; 278 | margin: 0; 279 | } 280 | 281 | #id_config_jsoneditor, 282 | #id_config-0-config_jsoneditor{ 283 | border: 0px !important; 284 | height: auto !important; 285 | } 286 | 287 | /* support django admin inline */ 288 | 289 | div.jsoneditor > div > h3.controls{ 290 | background: transparent !important; 291 | } 292 | 293 | div.jsoneditor .inline-related h3 { 294 | color: #666 !important; 295 | background-color: #f8f8f8 !important; 296 | border-top: 1px solid #eee !important; 297 | border-bottom: 1px solid #eee !important; 298 | font-size: 13px !important; 299 | } 300 | 301 | #config-0.inline-related{ position: static } 302 | -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/js/jsonschema_widget.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openwisp/django-jsonschema-widget/8a1a86eceac96645fd855adf2f6a7f2cf89ff17e/django_jsonschema_widget/static/django-jsonschema-widget/js/jsonschema_widget.js -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/js/lib/tomorrow_night_bright.js: -------------------------------------------------------------------------------- 1 | ace.define("ace/theme/tomorrow_night_bright",["require","exports","module","ace/lib/dom"], function(acequire, exports, module) { 2 | 3 | exports.isDark = true; 4 | exports.cssClass = "ace-tomorrow-night-bright"; 5 | exports.cssText = ".ace-tomorrow-night-bright .ace_gutter {\ 6 | background: #1a1a1a;\ 7 | color: #DEDEDE\ 8 | }\ 9 | .ace-tomorrow-night-bright .ace_print-margin {\ 10 | width: 1px;\ 11 | background: #1a1a1a\ 12 | }\ 13 | .ace-tomorrow-night-bright {\ 14 | background-color: #000000;\ 15 | color: #DEDEDE\ 16 | }\ 17 | .ace-tomorrow-night-bright .ace_cursor {\ 18 | color: #9F9F9F\ 19 | }\ 20 | .ace-tomorrow-night-bright .ace_marker-layer .ace_selection {\ 21 | background: #424242\ 22 | }\ 23 | .ace-tomorrow-night-bright.ace_multiselect .ace_selection.ace_start {\ 24 | box-shadow: 0 0 3px 0px #000000;\ 25 | }\ 26 | .ace-tomorrow-night-bright .ace_marker-layer .ace_step {\ 27 | background: rgb(102, 82, 0)\ 28 | }\ 29 | .ace-tomorrow-night-bright .ace_marker-layer .ace_bracket {\ 30 | margin: -1px 0 0 -1px;\ 31 | border: 1px solid #888888\ 32 | }\ 33 | .ace-tomorrow-night-bright .ace_marker-layer .ace_highlight {\ 34 | border: 1px solid rgb(110, 119, 0);\ 35 | border-bottom: 0;\ 36 | box-shadow: inset 0 -1px rgb(110, 119, 0);\ 37 | margin: -1px 0 0 -1px;\ 38 | background: rgba(255, 235, 0, 0.1)\ 39 | }\ 40 | .ace-tomorrow-night-bright .ace_marker-layer .ace_active-line {\ 41 | background: #2A2A2A\ 42 | }\ 43 | .ace-tomorrow-night-bright .ace_gutter-active-line {\ 44 | background-color: #2A2A2A\ 45 | }\ 46 | .ace-tomorrow-night-bright .ace_stack {\ 47 | background-color: rgb(66, 90, 44)\ 48 | }\ 49 | .ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word {\ 50 | border: 1px solid #888888\ 51 | }\ 52 | .ace-tomorrow-night-bright .ace_invisible {\ 53 | color: #343434\ 54 | }\ 55 | .ace-tomorrow-night-bright .ace_keyword,\ 56 | .ace-tomorrow-night-bright .ace_meta,\ 57 | .ace-tomorrow-night-bright .ace_storage,\ 58 | .ace-tomorrow-night-bright .ace_storage.ace_type,\ 59 | .ace-tomorrow-night-bright .ace_support.ace_type {\ 60 | color: #C397D8\ 61 | }\ 62 | .ace-tomorrow-night-bright .ace_keyword.ace_operator {\ 63 | color: #70C0B1\ 64 | }\ 65 | .ace-tomorrow-night-bright .ace_constant.ace_character,\ 66 | .ace-tomorrow-night-bright .ace_constant.ace_language,\ 67 | .ace-tomorrow-night-bright .ace_constant.ace_numeric,\ 68 | .ace-tomorrow-night-bright .ace_keyword.ace_other.ace_unit,\ 69 | .ace-tomorrow-night-bright .ace_support.ace_constant,\ 70 | .ace-tomorrow-night-bright .ace_variable.ace_parameter {\ 71 | color: #E78C45\ 72 | }\ 73 | .ace-tomorrow-night-bright .ace_constant.ace_other {\ 74 | color: #EEEEEE\ 75 | }\ 76 | .ace-tomorrow-night-bright .ace_invalid {\ 77 | color: #CED2CF;\ 78 | background-color: #DF5F5F\ 79 | }\ 80 | .ace-tomorrow-night-bright .ace_invalid.ace_deprecated {\ 81 | color: #CED2CF;\ 82 | background-color: #B798BF\ 83 | }\ 84 | .ace-tomorrow-night-bright .ace_fold {\ 85 | background-color: #7AA6DA;\ 86 | border-color: #DEDEDE\ 87 | }\ 88 | .ace-tomorrow-night-bright .ace_entity.ace_name.ace_function,\ 89 | .ace-tomorrow-night-bright .ace_support.ace_function,\ 90 | .ace-tomorrow-night-bright .ace_variable {\ 91 | color: #7AA6DA\ 92 | }\ 93 | .ace-tomorrow-night-bright .ace_support.ace_class,\ 94 | .ace-tomorrow-night-bright .ace_support.ace_type {\ 95 | color: #E7C547\ 96 | }\ 97 | .ace-tomorrow-night-bright .ace_heading,\ 98 | .ace-tomorrow-night-bright .ace_markup.ace_heading,\ 99 | .ace-tomorrow-night-bright .ace_string {\ 100 | color: #B9CA4A\ 101 | }\ 102 | .ace-tomorrow-night-bright .ace_entity.ace_name.ace_tag,\ 103 | .ace-tomorrow-night-bright .ace_entity.ace_other.ace_attribute-name,\ 104 | .ace-tomorrow-night-bright .ace_meta.ace_tag,\ 105 | .ace-tomorrow-night-bright .ace_string.ace_regexp,\ 106 | .ace-tomorrow-night-bright .ace_variable {\ 107 | color: #D54E53\ 108 | }\ 109 | .ace-tomorrow-night-bright .ace_comment {\ 110 | color: #969896\ 111 | }\ 112 | .ace-tomorrow-night-bright .ace_c9searchresults.ace_keyword {\ 113 | color: #C2C280\ 114 | }\ 115 | .ace-tomorrow-night-bright .ace_indent-guide {\ 116 | background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y\ 117 | }"; 118 | 119 | var dom = acequire("../lib/dom"); 120 | dom.importCssString(exports.cssText, exports.cssClass); 121 | }); 122 | -------------------------------------------------------------------------------- /django_jsonschema_widget/static/django-jsonschema-widget/js/widget.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | var inFullScreenMode = false, 3 | oldHeight = 0, 4 | oldWidth = 0; 5 | var toggleFullScreen = function(){ 6 | var advanced = $('#advanced_editor'); 7 | if(!inFullScreenMode){ 8 | // store the old height and width of the editor before going to fullscreen mode in order to be able to restore them 9 | oldHeight = advanced.height(); 10 | oldWidth = advanced.width(); 11 | advanced.addClass('full-screen').height($(window).height()).width(window.outerWidth); 12 | $('body').addClass('editor-full'); 13 | $(window).resize(function(){ 14 | advanced.height($(window).height()).width(window.outerWidth); 15 | }); 16 | inFullScreenMode = true; 17 | advanced.find('.jsoneditor-menu a').show(); 18 | advanced.find('.jsoneditor-menu label').show(); 19 | window.scrollTo(0,0); 20 | } 21 | else{ 22 | advanced.removeClass('full-screen').height(oldHeight).width(oldWidth); 23 | $('body').removeClass('editor-full'); 24 | // unbind all events listened to while going to full screen mode 25 | $(window).unbind('resize'); 26 | inFullScreenMode = false; 27 | document.getElementById('advanced_editor').scrollIntoView(true); 28 | advanced.find('.jsoneditor-menu a').hide(); 29 | advanced.find('.jsoneditor-menu label').hide(); 30 | } 31 | }; 32 | 33 | var initAdvancedEditor = function(target, data, schema, disableSchema){ 34 | var advanced = $("
"); 35 | $(advanced).insertBefore($(target)); 36 | $(target).hide(); 37 | // if disableSchema is true, do not validate againsts schema, default is false 38 | schema = disableSchema ? {} : schema; 39 | var options = { 40 | mode:'code', 41 | theme: 'ace/theme/tomorrow_night_bright', 42 | indentation: 4, 43 | onEditable: function(node){ 44 | return true; 45 | }, 46 | onChange:function() { 47 | $(target).val(editor.getText()); 48 | }, 49 | schema: schema 50 | }; 51 | 52 | var editor = new advancedJSONEditor(document.getElementById(advanced.attr('id')), options, data); 53 | editor.aceEditor.setOptions({ 54 | fontSize: 14, 55 | showInvisibles: true 56 | }); 57 | // remove powered by ace link 58 | advanced.find('.jsoneditor-menu a').remove(); 59 | // add listener to .screen-mode button for toggleScreenMode 60 | advanced.parents('.field-config').find('.screen-mode').click(toggleFullScreen); 61 | // add controls to the editor header 62 | advanced.find('.jsoneditor-menu') 63 | .append($(' back to normal mode')) 64 | .append(advanced.parents('.field-config').find('#netjsonconfig-hint') 65 | .clone(true) 66 | .attr('id','netjsonconfig-hint-advancedmode')); 67 | return editor; 68 | }; 69 | 70 | // returns true if JSON is well formed 71 | // and valid according to its schema 72 | var isValidJson = function(advanced){ 73 | var valid; 74 | try{ 75 | valid = advanced.validateSchema(advanced.get()); 76 | }catch (e){ 77 | valid = false; 78 | } 79 | return valid; 80 | }; 81 | 82 | var alertInvalidJson = function(){ 83 | alert("The JSON entered is not valid"); 84 | }; 85 | 86 | var loadUi = function(el, backend, schemas, setInitialValue){ 87 | var field = $(el), 88 | form = field.parents('form').eq(0), 89 | value = JSON.parse(field.val()), 90 | id = field.attr('id') + '_jsoneditor', 91 | initialField = $('#initial-' + field.attr('id')), 92 | container = field.parents('.form-row').eq(0), 93 | labelText = container.find('label:not(#netjsonconfig-hint)').text(), 94 | startval = $.isEmptyObject(value) ? null : value, 95 | editorContainer = $('#' + id), 96 | html, editor, options, wrapper, header, 97 | getEditorValue, updateRaw, advancedEditor, 98 | $advancedEl; 99 | // inject editor unless already present 100 | if(!editorContainer.length){ 101 | html = '
'; 102 | html += '

'+ labelText +'

'; 103 | html += '
'; 104 | html += '
'; 105 | container.hide().after(html); 106 | editorContainer = $('#' + id); 107 | } 108 | else{ 109 | editorContainer.html(''); 110 | } 111 | 112 | // stop operation if empty admin inline object 113 | if (field.attr('id').indexOf('__prefix__') > -1) { 114 | return; 115 | } 116 | 117 | wrapper = editorContainer.parents('.jsoneditor-wrapper'); 118 | options = { 119 | theme: 'django', 120 | disable_collapse: true, 121 | disable_edit_json: true, 122 | startval: startval, 123 | keep_oneof_values: false, 124 | show_errors: 'change', 125 | // if no backend selected use empty schema 126 | schema: backend ? schemas[backend] : {} 127 | }; 128 | if (field.attr("data-options") !== undefined) { 129 | $.extend(options, JSON.parse(field.attr("data-options"))); 130 | } 131 | editor = new JSONEditor(document.getElementById(id), options); 132 | // initialise advanced json editor here (disable schema validation in VPN admin) 133 | advancedEditor = initAdvancedEditor(field, value, options.schema, $('#vpn_form').length === 1); 134 | $advancedEl = $('#advanced_editor'); 135 | getEditorValue = function(){ 136 | return JSON.stringify(editor.getValue(), null, 4); 137 | }; 138 | updateRaw = function(){ 139 | field.val(getEditorValue()); 140 | }; 141 | 142 | editor.editors.root.addproperty_button.value = 'Configuration Menu'; 143 | // set initial field value to the schema default 144 | if (setInitialValue) { 145 | initialField.val(getEditorValue()); 146 | } 147 | // update raw value on change event 148 | editor.on('change', updateRaw); 149 | 150 | // update raw value before form submit 151 | form.submit(function(e){ 152 | if ($advancedEl.is(':hidden')) { return; } 153 | // only submit the form if the json in the advanced editor is valid 154 | if(!isValidJson(advancedEditor)){ 155 | e.preventDefault(); 156 | alertInvalidJson(); 157 | } 158 | else{ 159 | if (container.is(':hidden')) { updateRaw(); } 160 | } 161 | }); 162 | 163 | // add advanced edit button 164 | header = editorContainer.find('> div > h3'); 165 | header.find('span:first-child').hide(); // hides editor title 166 | header.attr('class', 'controls'); 167 | // move advanced mode button in auto-generated UI 168 | container.find('.advanced-mode').clone().prependTo(header); 169 | // advanced mode button 170 | header.find('.advanced-mode').click(function(){ 171 | // update autogenrated advanced json editor with new data 172 | advancedEditor.set(JSON.parse(field.val())); 173 | wrapper.hide(); 174 | container.show(); 175 | // set the advanced editor container to full screen mode 176 | toggleFullScreen(); 177 | }); 178 | 179 | // back to normal mode button 180 | $advancedEl.find('.jsoneditor-exit').click(function(){ 181 | // check if json in advanced mode is valid before coming back to normal mode 182 | if(isValidJson(advancedEditor)){ 183 | // update autogenerated UI 184 | editor.setValue(JSON.parse(field.val())); 185 | toggleFullScreen(); 186 | container.hide(); 187 | wrapper.show(); 188 | } 189 | else{ 190 | alertInvalidJson(); 191 | } 192 | }); 193 | 194 | // re-enable click on netjsonconfig hint 195 | $advancedEl.find('#netjsonconfig-hint-advancedmode a').click(function(){ 196 | var window_ = window.open($(this).attr('href'), '_blank'); 197 | window_.focus(); 198 | }); 199 | 200 | // allow to add object properties by pressing enter 201 | form.on('keypress', '.jsoneditor .modal input[type=text]', function(e){ 202 | if(e.keyCode == 13){ 203 | e.preventDefault(); 204 | $(e.target).siblings('input.json-editor-btn-add').trigger('click'); 205 | $(e.target).val(''); 206 | } 207 | }); 208 | }; 209 | 210 | var bindLoadUi = function(){ 211 | $.getJSON(django._netjsonconfigSchemaUrl, function(schemas){ 212 | $('.jsoneditor-raw').each(function(i, el){ 213 | var field = $(el), 214 | schema = field.attr("data-schema"), 215 | schema_selector = field.attr("data-schema-selector"); 216 | if (schema !== undefined) { 217 | loadUi(el, schema, schemas, true); 218 | } else { 219 | if(schema_selector === undefined) { 220 | schema_selector = '#id_backend, #id_config-0-backend'; 221 | } 222 | var backend = $(schema_selector); 223 | // load first time 224 | loadUi(el, backend.val(), schemas, true); 225 | // reload when backend is changed 226 | backend.change(function(){ 227 | loadUi(el, backend.val(), schemas); 228 | }); 229 | } 230 | }); 231 | }); 232 | }; 233 | 234 | $(function() { 235 | var add_config = $('#config-group.inline-group .add-row'); 236 | // if configuration is admin inline 237 | // load it when add button is clicked 238 | add_config.click(bindLoadUi); 239 | // otherwise load immediately 240 | bindLoadUi(); 241 | }); 242 | }(django.jQuery)); 243 | 244 | var matchKey = (function () { 245 | var elem = document.documentElement; 246 | if (elem.matches) { return 'matches'; } 247 | if (elem.webkitMatchesSelector) { return 'webkitMatchesSelector'; } 248 | if (elem.mozMatchesSelector) { return 'mozMatchesSelector'; } 249 | if (elem.msMatchesSelector) { return 'msMatchesSelector'; } 250 | if (elem.oMatchesSelector) { return 'oMatchesSelector'; } 251 | }()); 252 | // JSON-Schema Edtor django theme 253 | JSONEditor.defaults.themes.django = JSONEditor.AbstractTheme.extend({ 254 | getContainer: function() { 255 | return document.createElement('div'); 256 | }, 257 | getFloatRightLinkHolder: function() { 258 | var el = document.createElement('div'); 259 | el.style = el.style || {}; 260 | el.style.cssFloat = 'right'; 261 | el.style.marginLeft = '10px'; 262 | return el; 263 | }, 264 | getModal: function() { 265 | var el = document.createElement('div'); 266 | el.className = 'modal'; 267 | el.style.display = 'none'; 268 | return el; 269 | }, 270 | getGridContainer: function() { 271 | var el = document.createElement('div'); 272 | el.className = 'grid-container'; 273 | return el; 274 | }, 275 | getGridRow: function() { 276 | var el = document.createElement('div'); 277 | el.className = 'grid-row'; 278 | return el; 279 | }, 280 | getGridColumn: function() { 281 | var el = document.createElement('div'); 282 | el.className = 'grid-column'; 283 | return el; 284 | }, 285 | setGridColumnSize: function(el, size) { 286 | return el; 287 | }, 288 | getLink: function(text) { 289 | var el = document.createElement('a'); 290 | el.setAttribute('href', '#'); 291 | el.appendChild(document.createTextNode(text)); 292 | return el; 293 | }, 294 | disableHeader: function(header) { 295 | header.style.color = '#ccc'; 296 | }, 297 | disableLabel: function(label) { 298 | label.style.color = '#ccc'; 299 | }, 300 | enableHeader: function(header) { 301 | header.style.color = ''; 302 | }, 303 | enableLabel: function(label) { 304 | label.style.color = ''; 305 | }, 306 | getFormInputLabel: function(text) { 307 | var el = document.createElement('label'); 308 | el.appendChild(document.createTextNode(text)); 309 | return el; 310 | }, 311 | getCheckboxLabel: function(text) { 312 | var el = this.getFormInputLabel(text); 313 | return el; 314 | }, 315 | getHeader: function(text) { 316 | var el = document.createElement('h3'); 317 | if (typeof text === "string") { 318 | el.textContent = text; 319 | } else { 320 | el.appendChild(text); 321 | } 322 | return el; 323 | }, 324 | getCheckbox: function() { 325 | var el = this.getFormInputField('checkbox'); 326 | el.style.display = 'inline-block'; 327 | el.style.width = 'auto'; 328 | return el; 329 | }, 330 | getMultiCheckboxHolder: function(controls, label, description) { 331 | var el = document.createElement('div'), 332 | i; 333 | 334 | if (label) { 335 | label.style.display = 'block'; 336 | el.appendChild(label); 337 | } 338 | 339 | for (i in controls) { 340 | if (!controls.hasOwnProperty(i)) { continue; } 341 | controls[i].style.display = 'inline-block'; 342 | controls[i].style.marginRight = '20px'; 343 | el.appendChild(controls[i]); 344 | } 345 | 346 | if (description) { el.appendChild(description); } 347 | 348 | return el; 349 | }, 350 | getSelectInput: function(options) { 351 | var select = document.createElement('select'); 352 | if (options) { this.setSelectOptions(select, options); } 353 | return select; 354 | }, 355 | getSwitcher: function(options) { 356 | var switcher = this.getSelectInput(options); 357 | switcher.className = 'switcher'; 358 | return switcher; 359 | }, 360 | getSwitcherOptions: function(switcher) { 361 | return switcher.getElementsByTagName('option'); 362 | }, 363 | setSwitcherOptions: function(switcher, options, titles) { 364 | this.setSelectOptions(switcher, options, titles); 365 | }, 366 | setSelectOptions: function(select, options, titles) { 367 | titles = titles || []; 368 | select.innerHTML = ''; 369 | var i, option; 370 | for (i = 0; i < options.length; i++) { 371 | option = document.createElement('option'); 372 | option.setAttribute('value', options[i]); 373 | option.textContent = titles[i] || options[i]; 374 | select.appendChild(option); 375 | } 376 | }, 377 | getTextareaInput: function() { 378 | var el = document.createElement('textarea'); 379 | el.className = 'vLargeTextField'; 380 | return el; 381 | }, 382 | getRangeInput: function(min, max, step) { 383 | var el = this.getFormInputField('range'); 384 | el.setAttribute('min', min); 385 | el.setAttribute('max', max); 386 | el.setAttribute('step', step); 387 | return el; 388 | }, 389 | getFormInputField: function(type) { 390 | var el = document.createElement('input'); 391 | el.className = 'vTextField'; 392 | el.setAttribute('type', type); 393 | return el; 394 | }, 395 | afterInputReady: function(input) { 396 | return; 397 | }, 398 | getFormControl: function(label, input, description) { 399 | var el = document.createElement('div'); 400 | el.className = 'form-row'; 401 | if (label) { el.appendChild(label); } 402 | if (input.type === 'checkbox') { 403 | label.insertBefore(input, label.firstChild); 404 | } else { 405 | el.appendChild(input); 406 | } 407 | if (description) { el.appendChild(description); } 408 | return el; 409 | }, 410 | getIndentedPanel: function() { 411 | var el = document.createElement('div'); 412 | el.className = 'inline-related'; 413 | return el; 414 | }, 415 | getChildEditorHolder: function() { 416 | var el = document.createElement('div'); 417 | el.className = 'inline-group'; 418 | return el; 419 | }, 420 | getDescription: function(text) { 421 | var el = document.createElement('p'); 422 | el.className = 'help'; 423 | el.innerHTML = text; 424 | return el; 425 | }, 426 | getCheckboxDescription: function(text) { 427 | return this.getDescription(text); 428 | }, 429 | getFormInputDescription: function(text) { 430 | return this.getDescription(text); 431 | }, 432 | getHeaderButtonHolder: function() { 433 | var el = document.createElement('span'); 434 | el.className = 'control'; 435 | return el; 436 | }, 437 | getButtonHolder: function() { 438 | var el = document.createElement('div'); 439 | el.className = 'control'; 440 | return el; 441 | }, 442 | getButton: function(text, icon, title) { 443 | var el = document.createElement('input'), 444 | className = 'button'; 445 | if (text.indexOf('Delete') > -1) { 446 | className += ' deletelink'; 447 | } 448 | el.className = className; 449 | el.type = 'button'; 450 | this.setButtonText(el, text, icon, title); 451 | return el; 452 | }, 453 | setButtonText: function(button, text, icon, title) { 454 | button.value = text; 455 | if (title) { button.setAttribute('title', title); } 456 | }, 457 | getTable: function() { 458 | return document.createElement('table'); 459 | }, 460 | getTableRow: function() { 461 | return document.createElement('tr'); 462 | }, 463 | getTableHead: function() { 464 | return document.createElement('thead'); 465 | }, 466 | getTableBody: function() { 467 | return document.createElement('tbody'); 468 | }, 469 | getTableHeaderCell: function(text) { 470 | var el = document.createElement('th'); 471 | el.textContent = text; 472 | return el; 473 | }, 474 | getTableCell: function() { 475 | var el = document.createElement('td'); 476 | return el; 477 | }, 478 | getErrorMessage: function(text) { 479 | var el = document.createElement('p'); 480 | el.style = el.style || {}; 481 | el.style.color = 'red'; 482 | el.appendChild(document.createTextNode(text)); 483 | return el; 484 | }, 485 | addInputError: function(input, text) { 486 | input.parentNode.className += ' errors'; 487 | if(!input.errmsg) { 488 | input.errmsg = document.createElement('li'); 489 | var ul = document.createElement('ul'); 490 | ul.className = 'errorlist'; 491 | ul.appendChild(input.errmsg); 492 | input.parentNode.appendChild(ul); 493 | } 494 | else { 495 | input.errmsg.parentNode.style.display = ''; 496 | } 497 | input.errmsg.textContent = text; 498 | }, 499 | removeInputError: function(input) { 500 | if(!input.errmsg) { return; } 501 | input.errmsg.parentNode.style.display = 'none'; 502 | input.parentNode.className = input.parentNode.className.replace(/\s?errors/g,''); 503 | }, 504 | addTableRowError: function(row) { return; }, 505 | removeTableRowError: function(row) { return; }, 506 | getTabHolder: function() { 507 | var el = document.createElement('div'); 508 | el.innerHTML = "
"; 509 | return el; 510 | }, 511 | applyStyles: function(el, styles) { 512 | el.style = el.style || {}; 513 | var i; 514 | for (i in styles) { 515 | if (!styles.hasOwnProperty(i)) { continue; } 516 | el.style[i] = styles[i]; 517 | } 518 | }, 519 | closest: function(elem, selector) { 520 | while (elem && elem !== document) { 521 | if (matchKey) { 522 | if (elem[matchKey](selector)) { 523 | return elem; 524 | } 525 | elem = elem.parentNode; 526 | } else { 527 | return false; 528 | } 529 | } 530 | return false; 531 | }, 532 | getTab: function(span) { 533 | var el = document.createElement('div'); 534 | el.appendChild(span); 535 | el.style = el.style || {}; 536 | this.applyStyles(el, { 537 | border: '1px solid #ccc', 538 | borderWidth: '1px 0 1px 1px', 539 | textAlign: 'center', 540 | lineHeight: '30px', 541 | borderRadius: '5px', 542 | borderBottomRightRadius: 0, 543 | borderTopRightRadius: 0, 544 | fontWeight: 'bold', 545 | cursor: 'pointer' 546 | }); 547 | return el; 548 | }, 549 | getTabContentHolder: function(tab_holder) { 550 | return tab_holder.children[1]; 551 | }, 552 | getTabContent: function() { 553 | return this.getIndentedPanel(); 554 | }, 555 | markTabActive: function(tab) { 556 | this.applyStyles(tab, { 557 | opacity: 1, 558 | background: 'white' 559 | }); 560 | }, 561 | markTabInactive: function(tab) { 562 | this.applyStyles(tab, { 563 | opacity: 0.5, 564 | background: '' 565 | }); 566 | }, 567 | addTab: function(holder, tab) { 568 | holder.children[0].appendChild(tab); 569 | }, 570 | getBlockLink: function() { 571 | var link = document.createElement('a'); 572 | link.style.display = 'block'; 573 | return link; 574 | }, 575 | getBlockLinkHolder: function() { 576 | var el = document.createElement('div'); 577 | return el; 578 | }, 579 | getLinksHolder: function() { 580 | var el = document.createElement('div'); 581 | return el; 582 | }, 583 | createMediaLink: function(holder, link, media) { 584 | holder.appendChild(link); 585 | media.style.width = '100%'; 586 | holder.appendChild(media); 587 | }, 588 | createImageLink: function(holder, link, image) { 589 | holder.appendChild(link); 590 | link.appendChild(image); 591 | } 592 | }); 593 | -------------------------------------------------------------------------------- /django_jsonschema_widget/templates/django_jsonschema_widget/base.html: -------------------------------------------------------------------------------- 1 | 2 | {% comment %} 3 | As the developer of this package, don't place anything here if you can help it 4 | since this allows developers to have interoperability between your template 5 | structure and their own. 6 | 7 | Example: Developer melding the 2SoD pattern to fit inside with another pattern:: 8 | 9 | {% extends "base.html" %} 10 | {% load static %} 11 | 12 | 13 | {% block extra_js %} 14 | 15 | 16 | {% block javascript %} 17 | 18 | {% endblock javascript %} 19 | 20 | {% endblock extra_js %} 21 | {% endcomment %} 22 | -------------------------------------------------------------------------------- /django_jsonschema_widget/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.conf.urls import url 3 | from django.views.generic import TemplateView 4 | 5 | 6 | app_name = 'django_jsonschema_widget' 7 | urlpatterns = [ 8 | url(r'', TemplateView.as_view(template_name="base.html")), 9 | ] 10 | -------------------------------------------------------------------------------- /django_jsonschema_widget/widgets.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | from django import forms 4 | from django.contrib.admin.templatetags.admin_static import static 5 | from django.contrib.admin.widgets import AdminTextareaWidget 6 | from django.urls import reverse 7 | from django.utils.translation import ugettext_lazy as _ 8 | 9 | 10 | class JsonSchemaWidget(AdminTextareaWidget): 11 | """ 12 | JSON Schema Editor widget 13 | """ 14 | @property 15 | def media(self): 16 | prefix = 'django-jsonschema-widget' 17 | js = [static('{0}/js/{1}'.format(prefix, f)) 18 | for f in ('lib/advanced-mode.js', 19 | 'lib/tomorrow_night_bright.js', 20 | 'lib/jsonschema-ui.js', 21 | 'widget.js')] 22 | css = {'all': [static('{0}/css/{1}'.format(prefix, f)) 23 | for f in ('lib/jsonschema-ui.css', 24 | 'lib/advanced-mode.css')]} 25 | return forms.Media(js=js, css=css) 26 | 27 | def render(self, name, value, attrs=None, renderer=None, **kwargs): 28 | attrs['class'] = 'vLargeTextField jsoneditor-raw' 29 | html = """ 30 | 31 | 32 | 37 | """ 38 | html = html.format(_('Advanced mode (raw JSON)'), 39 | reverse('netjsonconfig:schema')) 40 | html += super(JsonSchemaWidget, self).render(name, value, attrs, renderer, **kwargs) 41 | return html 42 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/complexity.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/complexity.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/complexity" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/complexity" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/authors.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../AUTHORS.rst 2 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # complexity documentation build configuration file, created by 4 | # sphinx-quickstart on Tue Jul 9 22:26:36 2013. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | #sys.path.insert(0, os.path.abspath('.')) 20 | 21 | cwd = os.getcwd() 22 | parent = os.path.dirname(cwd) 23 | sys.path.append(parent) 24 | 25 | import jsonschema_widget 26 | 27 | # -- General configuration ----------------------------------------------------- 28 | 29 | # If your documentation needs a minimal Sphinx version, state it here. 30 | #needs_sphinx = '1.0' 31 | 32 | # Add any Sphinx extension module names here, as strings. They can be extensions 33 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 34 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates'] 38 | 39 | # The suffix of source filenames. 40 | source_suffix = '.rst' 41 | 42 | # The encoding of source files. 43 | #source_encoding = 'utf-8-sig' 44 | 45 | # The master toctree document. 46 | master_doc = 'index' 47 | 48 | # General information about the project. 49 | project = u'django-jsonschema-widget' 50 | copyright = u'2018, Federico Capoano' 51 | 52 | # The version info for the project you're documenting, acts as replacement for 53 | # |version| and |release|, also used in various other places throughout the 54 | # built documents. 55 | # 56 | # The short X.Y version. 57 | version = jsonschema_widget.__version__ 58 | # The full version, including alpha/beta/rc tags. 59 | release = jsonschema_widget.__version__ 60 | 61 | # The language for content autogenerated by Sphinx. Refer to documentation 62 | # for a list of supported languages. 63 | #language = None 64 | 65 | # There are two options for replacing |today|: either, you set today to some 66 | # non-false value, then it is used: 67 | #today = '' 68 | # Else, today_fmt is used as the format for a strftime call. 69 | #today_fmt = '%B %d, %Y' 70 | 71 | # List of patterns, relative to source directory, that match files and 72 | # directories to ignore when looking for source files. 73 | exclude_patterns = ['_build'] 74 | 75 | # The reST default role (used for this markup: `text`) to use for all documents. 76 | #default_role = None 77 | 78 | # If true, '()' will be appended to :func: etc. cross-reference text. 79 | #add_function_parentheses = True 80 | 81 | # If true, the current module name will be prepended to all description 82 | # unit titles (such as .. function::). 83 | #add_module_names = True 84 | 85 | # If true, sectionauthor and moduleauthor directives will be shown in the 86 | # output. They are ignored by default. 87 | #show_authors = False 88 | 89 | # The name of the Pygments (syntax highlighting) style to use. 90 | pygments_style = 'sphinx' 91 | 92 | # A list of ignored prefixes for module index sorting. 93 | #modindex_common_prefix = [] 94 | 95 | # If true, keep warnings as "system message" paragraphs in the built documents. 96 | #keep_warnings = False 97 | 98 | 99 | # -- Options for HTML output --------------------------------------------------- 100 | 101 | # The theme to use for HTML and HTML Help pages. See the documentation for 102 | # a list of builtin themes. 103 | html_theme = 'default' 104 | 105 | # Theme options are theme-specific and customize the look and feel of a theme 106 | # further. For a list of options available for each theme, see the 107 | # documentation. 108 | #html_theme_options = {} 109 | 110 | # Add any paths that contain custom themes here, relative to this directory. 111 | #html_theme_path = [] 112 | 113 | # The name for this set of Sphinx documents. If None, it defaults to 114 | # " v documentation". 115 | #html_title = None 116 | 117 | # A shorter title for the navigation bar. Default is the same as html_title. 118 | #html_short_title = None 119 | 120 | # The name of an image file (relative to this directory) to place at the top 121 | # of the sidebar. 122 | #html_logo = None 123 | 124 | # The name of an image file (within the static path) to use as favicon of the 125 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 126 | # pixels large. 127 | #html_favicon = None 128 | 129 | # Add any paths that contain custom static files (such as style sheets) here, 130 | # relative to this directory. They are copied after the builtin static files, 131 | # so a file named "default.css" will overwrite the builtin "default.css". 132 | html_static_path = ['_static'] 133 | 134 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 135 | # using the given strftime format. 136 | #html_last_updated_fmt = '%b %d, %Y' 137 | 138 | # If true, SmartyPants will be used to convert quotes and dashes to 139 | # typographically correct entities. 140 | #html_use_smartypants = True 141 | 142 | # Custom sidebar templates, maps document names to template names. 143 | #html_sidebars = {} 144 | 145 | # Additional templates that should be rendered to pages, maps page names to 146 | # template names. 147 | #html_additional_pages = {} 148 | 149 | # If false, no module index is generated. 150 | #html_domain_indices = True 151 | 152 | # If false, no index is generated. 153 | #html_use_index = True 154 | 155 | # If true, the index is split into individual pages for each letter. 156 | #html_split_index = False 157 | 158 | # If true, links to the reST sources are added to the pages. 159 | #html_show_sourcelink = True 160 | 161 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 162 | #html_show_sphinx = True 163 | 164 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 165 | #html_show_copyright = True 166 | 167 | # If true, an OpenSearch description file will be output, and all pages will 168 | # contain a tag referring to it. The value of this option must be the 169 | # base URL from which the finished HTML is served. 170 | #html_use_opensearch = '' 171 | 172 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 173 | #html_file_suffix = None 174 | 175 | # Output file base name for HTML help builder. 176 | htmlhelp_basename = 'django-jsonschema-widgetdoc' 177 | 178 | 179 | # -- Options for LaTeX output -------------------------------------------------- 180 | 181 | latex_elements = { 182 | # The paper size ('letterpaper' or 'a4paper'). 183 | #'papersize': 'letterpaper', 184 | 185 | # The font size ('10pt', '11pt' or '12pt'). 186 | #'pointsize': '10pt', 187 | 188 | # Additional stuff for the LaTeX preamble. 189 | #'preamble': '', 190 | } 191 | 192 | # Grouping the document tree into LaTeX files. List of tuples 193 | # (source start file, target name, title, author, documentclass [howto/manual]). 194 | latex_documents = [ 195 | ('index', 'django-jsonschema-widget.tex', u'django-jsonschema-widget Documentation', 196 | u'Federico Capoano', 'manual'), 197 | ] 198 | 199 | # The name of an image file (relative to this directory) to place at the top of 200 | # the title page. 201 | #latex_logo = None 202 | 203 | # For "manual" documents, if this is true, then toplevel headings are parts, 204 | # not chapters. 205 | #latex_use_parts = False 206 | 207 | # If true, show page references after internal links. 208 | #latex_show_pagerefs = False 209 | 210 | # If true, show URL addresses after external links. 211 | #latex_show_urls = False 212 | 213 | # Documents to append as an appendix to all manuals. 214 | #latex_appendices = [] 215 | 216 | # If false, no module index is generated. 217 | #latex_domain_indices = True 218 | 219 | 220 | # -- Options for manual page output -------------------------------------------- 221 | 222 | # One entry per manual page. List of tuples 223 | # (source start file, name, description, authors, manual section). 224 | man_pages = [ 225 | ('index', 'django-jsonschema-widget', u'django-jsonschema-widget Documentation', 226 | [u'Federico Capoano'], 1) 227 | ] 228 | 229 | # If true, show URL addresses after external links. 230 | #man_show_urls = False 231 | 232 | 233 | # -- Options for Texinfo output ------------------------------------------------ 234 | 235 | # Grouping the document tree into Texinfo files. List of tuples 236 | # (source start file, target name, title, author, 237 | # dir menu entry, description, category) 238 | texinfo_documents = [ 239 | ('index', 'django-jsonschema-widget', u'django-jsonschema-widget Documentation', 240 | u'Federico Capoano', 'django-jsonschema-widget', 'One line description of project.', 241 | 'Miscellaneous'), 242 | ] 243 | 244 | # Documents to append as an appendix to all manuals. 245 | #texinfo_appendices = [] 246 | 247 | # If false, no module index is generated. 248 | #texinfo_domain_indices = True 249 | 250 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 251 | #texinfo_show_urls = 'footnote' 252 | 253 | # If true, do not generate a @detailmenu in the "Top" node's menu. 254 | #texinfo_no_detailmenu = False 255 | -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CONTRIBUTING.rst 2 | -------------------------------------------------------------------------------- /docs/history.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../HISTORY.rst 2 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to django-jsonschema-widget's documentation! 2 | ================================================================= 3 | 4 | Contents: 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | readme 10 | installation 11 | usage 12 | contributing 13 | authors 14 | history 15 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Installation 3 | ============ 4 | 5 | At the command line:: 6 | 7 | $ pip instal django-jsonschema-widget 8 | 9 | Or, if you have virtualenvwrapper installed:: 10 | 11 | $ mkvirtualenv django-jsonschema-widget 12 | $ pip install django-jsonschema-widget 13 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\complexity.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\complexity.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /docs/readme.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | Usage 3 | ===== 4 | 5 | To use django-jsonschema-widget in a project, add it to your `INSTALLED_APPS`: 6 | 7 | .. code-block:: python 8 | 9 | INSTALLED_APPS = ( 10 | ... 11 | 'jsonschema_widget.apps.JsonschemaWidgetConfig', 12 | ... 13 | ) 14 | 15 | Please add django-jsonschema-widget's URL patterns in your project's ``urls.py``: 16 | 17 | .. code-block:: python 18 | 19 | from jsonschema_widget import urls as jsonschema_widget_urls 20 | 21 | 22 | urlpatterns = [ 23 | ... 24 | url(r'^', include(jsonschema_widget_urls)), 25 | ... 26 | ] 27 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | bumpversion==0.5.3 2 | wheel>=0.31.1 3 | 4 | -------------------------------------------------------------------------------- /requirements-test.txt: -------------------------------------------------------------------------------- 1 | coverage==4.4.1 2 | mock>=1.0.1 3 | openwisp-utils[qa] 4 | tox>=3.5.1 5 | codecov>=2.0.0 6 | 7 | 8 | # Additional test requirements go here 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Additional requirements go here 2 | -------------------------------------------------------------------------------- /runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 3 | from __future__ import unicode_literals, absolute_import 4 | 5 | import os 6 | import sys 7 | 8 | import django 9 | from django.conf import settings 10 | from django.test.utils import get_runner 11 | 12 | 13 | def run_tests(*test_args): 14 | if not test_args: 15 | test_args = ['tests'] 16 | 17 | os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' 18 | django.setup() 19 | TestRunner = get_runner(settings) 20 | test_runner = TestRunner() 21 | failures = test_runner.run_tests(test_args) 22 | sys.exit(bool(failures)) 23 | 24 | 25 | if __name__ == '__main__': 26 | run_tests(*sys.argv[1:]) 27 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.1.0 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:setup.py] 7 | 8 | [bumpversion:file:django_jsonschema_widget/__init__.py] 9 | 10 | [wheel] 11 | universal = 1 12 | 13 | [flake8] 14 | ignore = D203 15 | exclude = 16 | django_jsonschema_widget/migrations, 17 | .git, 18 | .tox, 19 | docs/conf.py, 20 | build, 21 | dist 22 | max-line-length = 119 23 | 24 | [isort] 25 | line_length = 109 26 | skip = migrations, docs/source/conf.py 27 | combine_as_imports = true 28 | default_section = THIRDPARTY 29 | include_trailing_comma = true 30 | known_first_party = django_jsonschema_widget 31 | multi_line_output = 5 32 | not_skip = __init__.py 33 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import re 5 | import sys 6 | 7 | try: 8 | from setuptools import setup 9 | except ImportError: 10 | from distutils.core import setup 11 | 12 | 13 | def get_version(*file_paths): 14 | """Retrieves the version from jsonschema_widget/__init__.py""" 15 | filename = os.path.join(os.path.dirname(__file__), *file_paths) 16 | version_file = open(filename).read() 17 | version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", 18 | version_file, re.M) 19 | if version_match: 20 | return version_match.group(1) 21 | raise RuntimeError('Unable to find version string.') 22 | 23 | 24 | version = get_version("django_jsonschema_widget", "__init__.py") 25 | 26 | 27 | if sys.argv[-1] == 'publish': 28 | try: 29 | import wheel 30 | print("Wheel version: ", wheel.__version__) 31 | except ImportError: 32 | print('Wheel library missing. Please run "pip install wheel"') 33 | sys.exit() 34 | os.system('python setup.py sdist upload') 35 | os.system('python setup.py bdist_wheel upload') 36 | sys.exit() 37 | 38 | if sys.argv[-1] == 'tag': 39 | print("Tagging the version on git:") 40 | os.system("git tag -a %s -m 'version %s'" % (version, version)) 41 | os.system("git push --tags") 42 | sys.exit() 43 | 44 | readme = open('README.rst').read() 45 | history = open('HISTORY.rst').read().replace('.. :changelog:', '') 46 | 47 | setup( 48 | name='django-jsonschema-widget', 49 | version=version, 50 | description="""Configuration widget for embedded device.""", 51 | long_description=readme + '\n\n' + history, 52 | author='Federico Capoano', 53 | author_email='nemesis@ninux.org', 54 | url='https://github.com/openwisp/django-jsonschema-widget', 55 | packages=[ 56 | 'django_jsonschema_widget', 57 | ], 58 | include_package_data=True, 59 | install_requires=['django'], 60 | license="BSD", 61 | zip_safe=False, 62 | keywords='django-jsonschema-widget', 63 | classifiers=[ 64 | 'Development Status :: 3 - Alpha', 65 | 'Framework :: Django :: 1.11', 66 | 'Framework :: Django :: 2.0', 67 | 'Framework :: Django :: 2.1', 68 | 'Intended Audience :: Developers', 69 | 'License :: OSI Approved :: BSD License', 70 | 'Natural Language :: English', 71 | 'Programming Language :: Python :: 2', 72 | 'Programming Language :: Python :: 2.7', 73 | 'Programming Language :: Python :: 3', 74 | 'Programming Language :: Python :: 3.4', 75 | 'Programming Language :: Python :: 3.5', 76 | 'Programming Language :: Python :: 3.6', 77 | 'Programming Language :: Python :: 3.7', 78 | ], 79 | ) 80 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openwisp/django-jsonschema-widget/8a1a86eceac96645fd855adf2f6a7f2cf89ff17e/tests/__init__.py -------------------------------------------------------------------------------- /tests/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from __future__ import unicode_literals, absolute_import 4 | 5 | import os 6 | import sys 7 | 8 | if __name__ == "__main__": 9 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings") 10 | from django.core.management import execute_from_command_line 11 | 12 | execute_from_command_line(sys.argv) 13 | -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 2 | from __future__ import unicode_literals, absolute_import 3 | 4 | 5 | DEBUG = True 6 | USE_TZ = True 7 | 8 | # SECURITY WARNING: keep the secret key used in production secret! 9 | SECRET_KEY = "v+s=%bl$5s30!o@wnz1v^6##6pxl@0zs1iz+ie3q3%q+@t)igc" 10 | 11 | DATABASES = { 12 | "default": { 13 | "ENGINE": "django.db.backends.sqlite3", 14 | "NAME": ":memory:", 15 | } 16 | } 17 | 18 | ROOT_URLCONF = "tests.urls" 19 | STATIC_URL = "/static/" 20 | 21 | INSTALLED_APPS = [ 22 | "django.contrib.admin", 23 | "django.contrib.auth", 24 | "django.contrib.contenttypes", 25 | "django.contrib.sites", 26 | "django_jsonschema_widget", 27 | ] 28 | 29 | SITE_ID = 1 30 | -------------------------------------------------------------------------------- /tests/test_models.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | test_django-jsonschema-widget 6 | ------------ 7 | 8 | Tests for `django-jsonschema-widget` models module. 9 | """ 10 | 11 | from django.test import TestCase 12 | 13 | 14 | class TestJsonschema_widget(TestCase): 15 | 16 | def setUp(self): 17 | pass 18 | 19 | def test_something(self): 20 | pass 21 | 22 | def tearDown(self): 23 | pass 24 | -------------------------------------------------------------------------------- /tests/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals, absolute_import 3 | 4 | from django.conf.urls import url, include 5 | 6 | 7 | urlpatterns = [ 8 | url(r'^', include( 9 | 'django_jsonschema_widget.urls', 10 | namespace='django_jsonschema_widget') 11 | ), 12 | ] 13 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | {py35,py36}-django-21 4 | {py34,py35,py36}-django-20 5 | {py27,py34,py35,py36}-django-111 6 | 7 | [testenv] 8 | setenv = 9 | PYTHONPATH = {toxinidir}:{toxinidir}/django_jsonschema_widget 10 | commands = coverage run --source django_jsonschema_widget runtests.py 11 | deps = 12 | django-111: Django>=1.11,<1.12 13 | django-20: Django>=2.0,<2.1 14 | django-20: Django>=2.1,<2.2 15 | -r{toxinidir}/requirements-test.txt 16 | basepython = 17 | py36: python3.6 18 | py35: python3.5 19 | py34: python3.4 20 | py27: python2.7 21 | --------------------------------------------------------------------------------