├── .coveragerc ├── .gitignore ├── .gitmodules ├── .green ├── .jshintrc ├── .travis.yml ├── CHANGES.rst ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── docs ├── Makefile ├── _static │ ├── custom.css │ ├── custom_ja.css │ └── skyblue.min.css ├── _templates │ └── layout.html ├── changes.rst ├── conf.py ├── dom.rst ├── event.rst ├── guide │ ├── dom.md │ ├── freezing.md │ ├── index.rst │ ├── load_resource.md │ ├── new_features.md │ ├── samples │ │ ├── dom1.py │ │ ├── dom2.py │ │ ├── dom3.py │ │ ├── dom4.py │ │ ├── new1.py │ │ ├── new2.py │ │ ├── new3.py │ │ ├── static1.py │ │ ├── static2.py │ │ ├── static3.py │ │ ├── wdom1.py │ │ ├── wdom2.py │ │ ├── wdom3.py │ │ ├── wdom4.py │ │ ├── wdom5.py │ │ ├── wdom6.py │ │ └── wdom7.py │ ├── theming.md │ └── wdom.md ├── index.rst ├── node.rst ├── reference.rst ├── server.py ├── tag.rst └── webserver.md ├── dodo.py ├── mypy.ini ├── profile └── parser.py ├── requirements-dev.txt ├── requirements-docs.txt ├── requirements-test.txt ├── setup.py ├── tests ├── __init__.py ├── base.py ├── server │ ├── __init__.py │ ├── base.py │ └── test_server.py ├── test_css.py ├── test_document.py ├── test_element.py ├── test_event.py ├── test_imports.py ├── test_node.py ├── test_options.py ├── test_parser.py ├── test_pyppeteer │ ├── __init__.py │ ├── base.py │ ├── test_examples.py │ ├── test_node.py │ └── test_tag.py ├── test_selenium │ ├── __init__.py │ ├── base.py │ ├── test_example_module.py │ ├── test_examples.py │ ├── test_node.py │ ├── test_server.py │ ├── test_tag.py │ └── testdir │ │ └── test.css ├── test_tag.py ├── test_testing.py ├── test_themes.py ├── test_web_node.py └── test_window.py ├── tox.ini └── wdom ├── __init__.py ├── _static ├── css │ ├── bagpakk.min.css │ ├── baseguide.min.css │ ├── bijou.min.css │ ├── groundwork.css │ ├── kathamo.min.css │ ├── kube.min.css │ ├── pure-extra.css │ ├── schema.min.css │ ├── siimple.min.css │ ├── skyblue.min.css │ ├── spark.min.css │ └── spectre.min.css ├── favicon.ico └── js │ ├── groundwork.all.js │ ├── spark.min.js │ └── wdom.js ├── _template ├── page.html └── page.mustache ├── css.py ├── document.py ├── element.py ├── event.py ├── examples ├── __init__.py ├── data_binding.py ├── drag.py ├── global_events.py ├── markdown_simple.py ├── rev_text.py ├── theming.py ├── timer.py └── todo.py ├── node.py ├── options.py ├── parser.py ├── server ├── __init__.py ├── _tornado.py ├── base.py └── handler.py ├── tag.py ├── themes ├── __init__.py ├── bagpakk.py ├── baseguide.py ├── bijou.py ├── blaze.py ├── bootstrap3.py ├── bootstrap4.py ├── bulma.py ├── concise.py ├── default.py ├── foundation.py ├── furtive.py ├── groundwork.py ├── ink.py ├── kathamo.py ├── kube.py ├── mdl.py ├── milligram.py ├── mui.py ├── papier.py ├── picnic.py ├── pure.py ├── schema.py ├── semantic.py ├── siimple.py ├── skeleton.py ├── skyblue.py ├── spark.py ├── spectre.py └── vital.py ├── util.py ├── web_node.py └── window.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit=*/themes/*,*/examples/*,wdom/__main__.py,setup.py 3 | source=wdom,tests 4 | -------------------------------------------------------------------------------- /.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 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # Virtualenv 28 | bin/ 29 | lib/ 30 | lib64 31 | pyvenv.cfg 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | .mypy_cache 50 | nosetests.xml 51 | coverage.xml 52 | *,cover 53 | .hypothesis/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ 67 | 68 | # pyenv python configuration file 69 | .python-version 70 | 71 | ###### direnv ###### 72 | .direnv 73 | .envrc 74 | 75 | ###### zsh-autoenv ###### 76 | .autoenv.zsh 77 | .autoenv_leave.zsh 78 | 79 | ### project specific ignore files 80 | wiki 81 | tmp 82 | .bumpversion.cfg 83 | pytest.xml 84 | chromedriver 85 | 86 | # node files 87 | node_modules 88 | 89 | # phantomjs 90 | ghostdriver.log 91 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miyakogi/wdom/a21bcd23e94baceee71161829f6897bee3fd39c1/.gitmodules -------------------------------------------------------------------------------- /.green: -------------------------------------------------------------------------------- 1 | verbose=1 2 | initializer=wdom.util.suppress_logging 3 | omit-patterns=*/themes/*,*/exapmles/* 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // Enhancement 3 | "unused": true, 4 | "undef": true, 5 | 6 | // Environments 7 | "browser": true, 8 | "devel": true, 9 | "esversion": 6, 10 | 11 | // Relaxes 12 | "asi": true, 13 | "sub": true, 14 | 15 | // Global variables 16 | "globals": { 17 | "riot": false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | dist: trustry 3 | language: python 4 | 5 | matrix: 6 | include: 7 | - python: 3.5 8 | env: TOXENV=py35 9 | - python: 3.6 10 | env: TOXENV=py36,flake8,mypy,pydocstyle,docs,codecov 11 | 12 | addons: 13 | chrome: stable 14 | 15 | install: 16 | - pip install tox 17 | 18 | script: 19 | - tox 20 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | Version 0.4 (next version) 2 | -------------------------- 3 | 4 | Version 0.3.1 (2018-03-06) 5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | * Update for tornado 5.0 8 | * [test] Update for pyppeteer 0.0.12 9 | 10 | Version 0.3 (2017-09-14) 11 | ------------------------ 12 | 13 | * Remove testing module from wdom package 14 | * Rename rimo.js to wdom.js 15 | 16 | Version 0.2.1 (2017-08-11) 17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18 | 19 | * Change metadata 20 | 21 | Version 0.2.0 (2017-08-11) 22 | -------------------------- 23 | 24 | * **Python 3.4 is NOT Supported** 25 | * Use async/await 26 | * Add type hints (pass mypy check) 27 | * Write docstrings (pass pydocstyle check) 28 | * Enable ``python setup.py test`` 29 | * Moved ``suppress_logging`` function from ``wdom.testing`` to ``wdom.misc`` 30 | * Improve auto-reload sequence 31 | * Parse html using custom elements 32 | * Find elements from customElementsRegistory 33 | * Move non-standard tag classes from ``wdom.tag`` to ``wdom.themes`` 34 | * Add ``wdom.tag.RawHtmlNode`` class 35 | * Support more events 36 | * Keyboard event support 37 | * Document/Window level event support 38 | * Drag and drop event support 39 | 40 | Version 0.1.8 (2017-07-23) 41 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 42 | 43 | * Raise warning if python version is < 3.5 44 | * Improve HTML parsing 45 | * Don't send events to unmounted DOM 46 | * Send multiple WS messages once 47 | 48 | Version 0.1.7 (2017-07-21) 49 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 50 | 51 | * Update PyPI metadata 52 | * Add shortcut functions (``server.start()`` and ``document.set_app()``) 53 | 54 | Version 0.1.6 (2017-07-21) 55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 56 | 57 | * Drop aiohttp support 58 | 59 | Version 0.1.5 (2017-06-03) 60 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 61 | 62 | * Tentatively disable aiohttp 63 | * Catch up recent updates 64 | * Add Concise CSS 65 | 66 | Version 0.1.4 (2016-05-20) 67 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 68 | 69 | * Examples are executable by one file 70 | * Upload document to readthedocs 71 | 72 | Version 0.1.3 (2016-05-17) 73 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 74 | 75 | * (bug fix) Add dependency of mypy-lang for python < 3.5 76 | 77 | Version 0.1.2 (2016-05-15) 78 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 79 | 80 | * ``TestCase.wait`` methods take two argument, ``timeout`` and ``times``. 81 | * Add ``wait_until`` method and ``timeout`` class variable on ``TestCase``. 82 | * Default value of ``TestCase.wait_time`` is same as local and travis ci. If 83 | longer wait time is required on travis, change ``wait_time`` on each test 84 | case. 85 | * Support access log on aiohttp server 86 | 87 | Version 0.1.1 (2016-05-15) 88 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 89 | 90 | * minor update on meta data 91 | 92 | Version 0.1 (2016-05-15) 93 | ------------------------ 94 | 95 | First public release. 96 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Hitoruki Takagi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include wdom/_static/js/wdom.js 4 | 5 | recursive-include tests *.py *.css 6 | recursive-include wdom/_static/css *.css 7 | recursive-exclude * __pycache__ 8 | recursive-exclude * *.py[co] 9 | 10 | recursive-include docs *.rst conf.py Makefile make.bat *.css *.js *.html 11 | recursive-exclude docs/_build * 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: release release-pypi release-github 2 | .PHONY: clean clean-test clean-pyc clean-build docs help 3 | .DEFAULT_GOAL := help 4 | define BROWSER_PYSCRIPT 5 | import os, webbrowser, sys 6 | try: 7 | from urllib import pathname2url 8 | except: 9 | from urllib.request import pathname2url 10 | 11 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 12 | endef 13 | export BROWSER_PYSCRIPT 14 | 15 | define PRINT_HELP_PYSCRIPT 16 | import re, sys 17 | 18 | for line in sys.stdin: 19 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 20 | if match: 21 | target, help = match.groups() 22 | print("%-20s %s" % (target, help)) 23 | endef 24 | export PRINT_HELP_PYSCRIPT 25 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 26 | 27 | help: 28 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 29 | 30 | clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts 31 | 32 | clean-build: ## remove build artifacts 33 | @echo "Remove build files (build/, dist/, .egg*, ...)." 34 | @rm -fr build/ 35 | @rm -fr dist/ 36 | @rm -fr .eggs/ 37 | @find . -name '*.egg-info' -exec rm -fr {} + 38 | @find . -name '*.egg' -exec rm -f {} + 39 | 40 | clean-pyc: ## remove Python file artifacts 41 | @echo "Remove python files (*.py[co], __pycache__, ...)." 42 | @find . -name '*.pyc' -exec rm -f {} + 43 | @find . -name '*.pyo' -exec rm -f {} + 44 | @find . -name '*~' -exec rm -f {} + 45 | @find . -name '__pycache__' -exec rm -fr {} + 46 | 47 | clean-test: ## remove test and coverage artifacts 48 | @echo "Remove test/coverage files (.coverage, htmlcov/)." 49 | @rm -f .coverage 50 | @rm -fr htmlcov/ 51 | @rm -f wdom/tests/browser/server/tmp*.py 52 | 53 | release: release-pypi release-github ## register pypi and push tags to github 54 | 55 | release-pypi: ## register pypi 56 | python setup.py sdist upload 57 | 58 | release-github: ## push tags to gihub 59 | git push origin --tags 60 | 61 | .PHONY: green green-cov green-single unittests 62 | green: ## run green test 63 | @echo "Run green." 64 | @cd maint && \ 65 | green -c ../.green ../wdom 66 | 67 | green-cov: # run green and calculate coverage 68 | @echo "Run green with coverage." 69 | @cd maint && \ 70 | green -r -c ../.green ../wdom 71 | 72 | green-single: ## run green with a single process 73 | @echo "Run green with a single process." 74 | @cd maint && \ 75 | green -s 1 -c ../.green ../wdom 76 | 77 | unittest: ## run python's unitttest 78 | @python -W ignore::ResourceWarning -m unittest discover wdom/tests 79 | 80 | .PHONY: flake8 81 | flake8: ## run flake8 syntax check 82 | flake8 wdom setup.py 83 | 84 | .PHONY: mypy 85 | mypy: ## run mypy type check 86 | mypy wdom 87 | 88 | .PHONY: pydocstyle 89 | pydocstyle: ## run pydocstyle check 90 | pydocstyle wdom 91 | 92 | # -n option is better but type hints refs are not found 93 | .PHONY: docs 94 | docs: ## build document 95 | @echo "Sphinx build start." 96 | sphinx-build -q -E -W -j 4 -b html docs docs/_build/html 97 | @echo "Sphinx build done." 98 | 99 | .PHONY: sphinx 100 | sphinx: ## run document build server 101 | @echo "### Sphinx Build Server Start ###" 102 | @python docs/server.py 103 | 104 | .PHONY: check 105 | check: ## run flake8, mypy, pydocstyle, sphinx-build 106 | @doit --verbosity 1 --process 4 --parallel-type thread 107 | 108 | .PHONY: test-all 109 | test-all: check green-cov ## run style check and test 110 | -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | h1.logo, div.section#wdom > h1 { 2 | font-family: "Raleway"; 3 | font-weight: 500; 4 | } 5 | 6 | a.headerlink { 7 | color: rgba(0, 0, 0, 0.1); 8 | } 9 | 10 | div.sphinxsidebarwrapper p.blurb { 11 | font-family: Lato, sans-serif; 12 | } 13 | 14 | div.sphinxsidebar li.toctree-l1 { 15 | font-family: Lato, sans-serif; 16 | } 17 | 18 | body { 19 | background-color: #fafafa 20 | } 21 | 22 | .search-btn { 23 | padding: 0 1em; 24 | font-family: Lato, sans-serif; 25 | font-weight: normal; 26 | line-height: normal; 27 | align-self: stretch; 28 | } 29 | -------------------------------------------------------------------------------- /docs/_static/custom_ja.css: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends 'alabaster/layout.html' %} 2 | {% block extrahead %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ super() }} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /docs/changes.rst: -------------------------------------------------------------------------------- 1 | Changes 2 | ======= 3 | 4 | .. include:: ../CHANGES.rst 5 | -------------------------------------------------------------------------------- /docs/dom.rst: -------------------------------------------------------------------------------- 1 | DOM API 2 | ======= 3 | 4 | (This section is not complete and not enough yet...) 5 | 6 | .. toctree:: 7 | tag 8 | node 9 | -------------------------------------------------------------------------------- /docs/event.rst: -------------------------------------------------------------------------------- 1 | Event API 2 | ========= 3 | 4 | .. currentmodule:: wdom.event 5 | 6 | .. autoclass:: wdom.event.Event 7 | :members: 8 | 9 | .. autoclass:: wdom.event.MouseEvent 10 | :members: 11 | 12 | .. autoclass:: wdom.event.KeyboardEvent 13 | :members: 14 | 15 | .. autoclass:: wdom.event.DragEvent 16 | :members: 17 | 18 | .. autoclass:: wdom.event.DataTransfer 19 | :members: 20 | 21 | .. autofunction:: wdom.event.create_event 22 | 23 | .. autoclass:: wdom.event.EventListener 24 | :members: 25 | 26 | .. autoclass:: wdom.event.EventTarget 27 | :members: 28 | -------------------------------------------------------------------------------- /docs/guide/freezing.md: -------------------------------------------------------------------------------- 1 | Freezing Application 2 | ==================== 3 | 4 | (to be described) 5 | 6 | Using cx_Freeze 7 | -------------- 8 | 9 | (to be described) 10 | 11 | Using Electron 12 | ------------- 13 | 14 | (to be described) 15 | -------------------------------------------------------------------------------- /docs/guide/index.rst: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | .. note:: 5 | This document is still incomplete, and will contain typos and mistakes in 6 | grammar due to my poor English skill. If you find any incorrect expression, 7 | please let me know at `issues `_ or 8 | send `PR `_. Any small improvements 9 | or suggestions (e.g. just changing **a** to **the**) are welcome! 10 | 11 | Contents 12 | -------- 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | dom 18 | wdom 19 | load_resource 20 | new_features 21 | theming 22 | freezing 23 | -------------------------------------------------------------------------------- /docs/guide/load_resource.md: -------------------------------------------------------------------------------- 1 | Loading Static Contents 2 | ======================= 3 | 4 | Contents on the Web 5 | ------------------- 6 | 7 | As an example, use `bootstrap`_. 8 | 9 | To use bootstrap, one css file (bootstrap.min.css) and two js files (jquery and 10 | bootstrap.min.js) are need to be loaded. 11 | To load css file, use `` tag and insert into the ``. 12 | And to load js files, use ` 20 | {% end %} 21 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /wdom/_template/page.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{title}} 6 | 7 | {{#headers}} 8 | {{{header}}} 9 | {{/headers}} 10 | {{#cssfiles}} 11 | 12 | {{/cssfiles}} 13 | 14 | 15 | {{#contents}} 16 | {{{content}}} 17 | {{/contents}} 18 | {{#jsfiles}} 19 | 20 | {{/jsfiles}} 21 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /wdom/examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/miyakogi/wdom/a21bcd23e94baceee71161829f6897bee3fd39c1/wdom/examples/__init__.py -------------------------------------------------------------------------------- /wdom/examples/data_binding.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | Data binding example 6 | ''' 7 | 8 | from wdom.themes import H1, Div, Input 9 | 10 | 11 | class App(Div): 12 | def __init__(self, *args, **kwargs): 13 | super().__init__(*args, **kwargs) 14 | self.text = H1(parent=self) 15 | self.text.textContent = 'Hello!' 16 | self.textbox = Input(parent=self) 17 | self.textbox.setAttribute('type', 'text') 18 | self.textbox.addEventListener('input', self.update) 19 | 20 | def update(self, event): 21 | self.text.textContent = self.textbox.getAttribute('value') 22 | 23 | 24 | def sample_app(**kwargs): 25 | return App() 26 | 27 | 28 | if __name__ == '__main__': 29 | from wdom.document import set_app 30 | from wdom import server 31 | set_app(sample_app()) 32 | server.start() 33 | -------------------------------------------------------------------------------- /wdom/examples/drag.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | Data binding example 6 | ''' 7 | 8 | from wdom import server 9 | from wdom.document import set_app, getElementByWdomId 10 | from wdom.themes import Div 11 | 12 | 13 | def dragstart(e): 14 | e.dataTransfer.setData('text/plain', e.currentTarget.wdom_id) 15 | 16 | 17 | def drop(e): 18 | start_elm = getElementByWdomId(e.dataTransfer.getData('text/plain')) 19 | current_color = e.currentTarget.style['background-color'] 20 | start_color = start_elm.style['background-color'] 21 | start_elm.style['background-color'] = current_color 22 | e.currentTarget.style['background-color'] = start_color 23 | 24 | 25 | class App(Div): 26 | def __init__(self, *args, **kwargs): 27 | super().__init__(*args, **kwargs) 28 | self.elm1 = Div(parent=self, draggable=True) 29 | self.elm1.setAttribute( 30 | 'style', 31 | 'width: 70px; height: 50px; display: inline-block' 32 | ) 33 | self.elm2 = self.elm1.cloneNode() 34 | self.elm3 = self.elm1.cloneNode() 35 | self.elm1.setAttribute('id', '1') 36 | self.elm2.setAttribute('id', '2') 37 | self.elm3.setAttribute('id', '3') 38 | self.append(self.elm2, self.elm3) 39 | self.elm1.style['background-color'] = 'red' 40 | self.elm2.style['background-color'] = 'green' 41 | self.elm3.style['background-color'] = 'blue' 42 | self.elm1.addEventListener('dragstart', dragstart) 43 | self.elm2.addEventListener('dragstart', dragstart) 44 | self.elm3.addEventListener('dragstart', dragstart) 45 | self.elm1.addEventListener('drop', drop) 46 | self.elm2.addEventListener('drop', drop) 47 | self.elm3.addEventListener('drop', drop) 48 | 49 | def update(self, event): 50 | self.text.textContent = self.textbox.getAttribute('value') 51 | 52 | 53 | def sample_app(**kwargs): 54 | return App() 55 | 56 | 57 | if __name__ == '__main__': 58 | set_app(sample_app()) 59 | server.start() 60 | -------------------------------------------------------------------------------- /wdom/examples/global_events.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from wdom import server 5 | from wdom.document import get_document, set_app 6 | from wdom.tag import H1, Div, Input 7 | 8 | 9 | def sample_page(**kwargs): 10 | doc = get_document() 11 | win = doc.defaultView 12 | app = Div() 13 | inp = Input(id='input', parent=app) 14 | win1 = H1(id='win1', parent=app) 15 | doc1 = H1(id='doc1', parent=app) 16 | input_view = H1(id='input_view', parent=app) 17 | 18 | def add_letter_doc(e): 19 | doc1.textContent = doc1.textContent + e.key 20 | 21 | def add_letter_win(e): 22 | win1.textContent = win1.textContent + e.key 23 | 24 | def input_handler(e): 25 | input_view.textContent = e.data 26 | 27 | doc.addEventListener('keypress', add_letter_doc) 28 | win.addEventListener('keypress', add_letter_win) 29 | inp.addEventListener('input', input_handler) 30 | return app 31 | 32 | 33 | def main(): 34 | set_app(sample_page()) 35 | server.start() 36 | 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /wdom/examples/markdown_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | try: 5 | import misaka as m 6 | from pygments import highlight 7 | from pygments.styles import get_all_styles 8 | from pygments.formatters import HtmlFormatter 9 | from pygments.lexers import get_lexer_by_name 10 | except ImportError: 11 | print('ERROR: Install `misaka` and `pygments` before run this example, ' 12 | 'by `pip install misaka pygments`.') 13 | exit() 14 | 15 | from wdom.options import config 16 | if config.theme is None: 17 | config.theme = 'concise' # fake command line `--theme` option 18 | from wdom.document import get_document # noqa: E402 19 | from wdom.themes import default, RawHtmlNode # noqa: E402 20 | from wdom.themes.default import Div, Textarea, Col6, Row, H1, Hr # noqa: E402 21 | from wdom.themes.default import Select, Option, Style # noqa: E402 22 | 23 | 24 | src = ''' 25 | ## Source Code Example 26 | 27 | ```py 28 | from collections import OrderedDict 29 | 30 | class MyDict(OrderedDict): 31 | def __init__(self, *args, **kwargs): 32 | super().__init__(*args, **kwargs) 33 | print('Create my dict') 34 | ``` 35 | ''' 36 | 37 | 38 | class HighlighterRenderer(m.HtmlRenderer): 39 | def blockcode(self, text, lang): 40 | if not lang: 41 | return '\n
{}
\n'.format(text.strip()) 42 | lexer = get_lexer_by_name(lang) 43 | formatter = HtmlFormatter() 44 | return highlight(text, lexer, formatter) 45 | 46 | 47 | class Editor(Row): 48 | def __init__(self, *args, **kwargs): 49 | super().__init__(*args, **kwargs) 50 | self.md = m.Markdown(HighlighterRenderer(), 51 | extensions=('fenced-code',)) 52 | self.css = Style(parent=self) 53 | 54 | self.setAttribute('style', 'height: 80vh;') 55 | editor_col = Col6(parent=self) 56 | self.editor = Textarea(parent=editor_col) 57 | self.editor.setAttribute('style', 'height: 80vh') 58 | 59 | viewer_col = Col6(parent=self) 60 | 61 | self.style_selector = Select() 62 | styles = sorted(get_all_styles()) 63 | styles.remove('default') 64 | self.style_selector.appendChild( 65 | Option('default', value='default', selected=True)) 66 | for style in styles: 67 | self.style_selector.appendChild(Option(style, value=style)) 68 | self.style_selector.addEventListener( 69 | 'change', lambda event: self.set_style(event.currentTarget.value)) 70 | 71 | self.viewer = Div() 72 | self.viewer.setAttribute( 73 | 'style', 74 | ''' 75 | height: 100%; 76 | min-height: 80vh; 77 | padding: 1em 2em; 78 | border: 1px solid #ddd; 79 | border-radius: 3px; 80 | ''', 81 | ) 82 | 83 | viewer_col.appendChild(self.style_selector) 84 | viewer_col.appendChild(self.viewer) 85 | 86 | self.editor.addEventListener('input', self.render) 87 | 88 | self.set_style('default') 89 | self.editor.textContent = src 90 | # TIPS: Wen just showing HTML, `appendChild(RawHtmlNode)` is better 91 | # than innerHTML on performance since it skips parse process. 92 | self.viewer.appendChild(RawHtmlNode(self.md(src))) 93 | 94 | def render(self, event): 95 | content = event.currentTarget.textContent 96 | # self.viewer.innerHTML = self.md(content) 97 | # TIPS: Same as above reason, RawHtml node is also better here 98 | self.viewer.replaceChild(RawHtmlNode(self.md(content)), 99 | self.viewer.firstChild) 100 | 101 | def set_style(self, style: str): 102 | self.css.innerHTML = HtmlFormatter(style=style).get_style_defs() 103 | 104 | 105 | def sample_page(**kwargs): 106 | get_document().register_theme(default) 107 | app = Div(style='width: 90vw; margin: auto') 108 | title = H1('Simple Markdown Editor', class_='text-center') 109 | app.appendChild(title) 110 | app.appendChild(Hr()) 111 | app.appendChild(Editor()) 112 | return app 113 | 114 | 115 | if __name__ == '__main__': 116 | from wdom.document import set_app 117 | from wdom import server 118 | set_app(sample_page()) 119 | server.start() 120 | -------------------------------------------------------------------------------- /wdom/examples/rev_text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from wdom.event import Event 5 | from wdom.themes import H1 6 | 7 | 8 | def rev_text(event: Event) -> None: 9 | elm = event.currentTarget 10 | elm.textContent = elm.textContent[::-1] 11 | 12 | 13 | def sample_app(**kwargs) -> H1: 14 | h1 = H1('Click!') 15 | h1.addEventListener('click', rev_text) 16 | return h1 17 | 18 | 19 | if __name__ == '__main__': 20 | from wdom.document import set_app 21 | from wdom import server 22 | set_app(sample_app()) 23 | server.start() 24 | -------------------------------------------------------------------------------- /wdom/examples/timer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import asyncio 5 | 6 | from wdom.themes import Div, H1, Container 7 | from wdom.themes import PrimaryButton, DangerButton, DefaultButton 8 | 9 | 10 | class Timer(Container): 11 | def __init__(self, *args, **kwargs): 12 | self._running = False 13 | self._count = 180 14 | self._interval = 0.01 15 | self._loop = asyncio.get_event_loop() 16 | super().__init__(*args, **kwargs) 17 | self._view = H1(parent=self) 18 | self.update() 19 | self._start_btn = PrimaryButton('start', parent=self, id='start_btn') 20 | self._start_btn.addEventListener('click', self.start) 21 | self._stop_btn = DangerButton('stop', parent=self, id='stop_btn') 22 | self._stop_btn.addEventListener('click', self.stop) 23 | self._reset_btn = DefaultButton('reset', parent=self, id='reset_btn') 24 | self._reset_btn.addEventListener('click', self.reset) 25 | 26 | def stop(self, event): 27 | self._running = False 28 | 29 | def start(self, event): 30 | self._running = True 31 | self._timer_loop() 32 | 33 | def reset(self, event): 34 | self._count = 180 35 | self.update() 36 | 37 | def _timer_loop(self): 38 | if self._running and self._count > 0: 39 | self._loop.call_later(self._interval, self._timer_loop) 40 | self._count -= self._interval 41 | self.update() 42 | 43 | def set(self, value): 44 | self._view.textContent = '{0:.2f}'.format(value) 45 | 46 | def update(self): 47 | self.set(self._count) 48 | 49 | 50 | def sample_app(**kwargs) -> Div: 51 | return Timer() 52 | 53 | 54 | if __name__ == '__main__': 55 | from wdom.document import set_app 56 | from wdom import server 57 | set_app(sample_app()) 58 | server.start() 59 | -------------------------------------------------------------------------------- /wdom/examples/todo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from wdom.themes.bootstrap3 import Tag, H1, Button, Div 5 | from wdom.themes.bootstrap3 import Container, FormGroup, TextInput 6 | from wdom.themes.bootstrap3 import css_files, js_files 7 | from wdom.document import get_document, Document 8 | 9 | 10 | class Item(Tag): 11 | tag = 'span' 12 | 13 | def __init__(self, *args, **kwargs) -> None: 14 | super().__init__(*args, **kwargs) 15 | 16 | 17 | def sample_page(**kwargs) -> Document: 18 | app = Container() 19 | title = H1(parent=app) 20 | title.textContent = 'Todo example' 21 | form = FormGroup(parent=app) 22 | text_input = TextInput() 23 | form.append(text_input) 24 | add_button = Button(parent=form) 25 | add_button.textContent = 'ADD' 26 | todo_list = Div(parent=app) 27 | todo_heading = Div(parent=todo_list) 28 | todo_heading.append('Todo list') 29 | # add_button.addEventListener('click') 30 | 31 | def new_item(event=None) -> Tag: 32 | item = Item() 33 | item.append('New Item') 34 | todo_list.append(item) 35 | return item 36 | 37 | add_button.addEventListener('click', new_item) 38 | 39 | page = get_document(app=app, **kwargs) 40 | for css in css_files: 41 | page.add_cssfile(css) 42 | for js in js_files: 43 | page.add_jsfile(js) 44 | 45 | return page 46 | -------------------------------------------------------------------------------- /wdom/options.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """This module defines options for wdom and wraps ``tornado.options``. 5 | 6 | Do not use ``tornado.options`` directly. 7 | 8 | When this module is loaded, automatically parse command line options. 9 | If need to parse command line optionas again, call ``parse_command_line`` 10 | function. 11 | """ 12 | 13 | import logging 14 | from argparse import ArgumentParser, Namespace 15 | from typing import Union 16 | 17 | from tornado.log import LogFormatter 18 | 19 | __all__ = [ 20 | 'parser', 21 | 'config', 22 | 'root_logger', 23 | 'set_loglevel', 24 | 'parse_command_line', 25 | ] 26 | 27 | # Setup root logger 28 | root_logger = logging.getLogger('wdom') # Root logger 29 | _log_handler = logging.StreamHandler() 30 | fmt = '%(color)s[%(levelname)1.1s:%(name)s]%(end_color)s ' 31 | fmt += '%(message)s' 32 | formatter = LogFormatter(fmt=fmt) 33 | _log_handler.setFormatter(formatter) 34 | root_logger.addHandler(_log_handler) 35 | root_logger.propagate = False 36 | 37 | # local logger 38 | logger = logging.getLogger(__name__) 39 | 40 | # setup argument parser 41 | config = Namespace() 42 | parser = ArgumentParser(prog='WDOM', argument_default=None) 43 | parser.add_argument( 44 | '--logging', choices=['debug', 'info', 'warn', 'error'], 45 | help='Set the log level (dafualt: `info`).', 46 | ) 47 | parser.add_argument( 48 | '--debug', default=False, action='store_const', const=True, 49 | help='Enable debug mode (dafualt: False).' 50 | ' Debug mode enables `--autoreload`, disables static file caching,' 51 | ' and sets default log level to `debug`.' 52 | ) 53 | parser.add_argument( 54 | '--address', default='localhost', 55 | help='Address to run server (default: `localhost`).' 56 | ) 57 | parser.add_argument( 58 | '--port', default=8888, type=int, 59 | help='Port to run server (defualt: 8888). If 0, use arbitrary free port.', 60 | ) 61 | parser.add_argument( 62 | '--autoreload', default=False, action='store_const', const=True, 63 | help='Watch files and restart when any files changed (default: False).', 64 | ) 65 | parser.add_argument( 66 | '--theme', default=None, type=str, 67 | help='Choose theme name to use with wdom.themes module.' 68 | ' By default (None) or unavailable name, use `wdom.tag`.' 69 | ) 70 | parser.add_argument( 71 | '--auto-shutdown', default=False, action='store_const', const=True, 72 | help='Terminate server process when all connections (browser tabs) closed' 73 | ' (default: False).', 74 | ) 75 | parser.add_argument( 76 | '--shutdown-wait', default=1.0, type=float, 77 | help='Seconds to wait until shutdown after all connections closed' 78 | ' when --auto-shutdown is enabled (default: 1.0 [sec]).', 79 | ) 80 | parser.add_argument( 81 | '--message-wait', default=0.005, type=float, 82 | help='Duration (seconds) to send WS messages (default: 0.005 [sec]).', 83 | ) 84 | parser.add_argument( 85 | '--open-browser', default=False, action='store_const', const=True, 86 | help='Open browser automatically (default: False).', 87 | ) 88 | parser.add_argument( 89 | '--browser', default=None, help='Browser name to open.' 90 | ' Only affects when used with --open-browser option.' 91 | ' Available values are keys of `webbrowser._browsers`.' 92 | ' When not specified or specified invalid value, open system\'s' 93 | ' default browser (default: None).', 94 | ) 95 | 96 | 97 | def level_to_int(level: Union[str, int]) -> int: 98 | if isinstance(level, int): 99 | if logging.NOTSET <= level <= logging.FATAL: 100 | return level 101 | else: 102 | raise ValueError('Log level must be 0 <= level <= 50,' 103 | 'but gat: {}'.format(level)) 104 | elif isinstance(level, str): 105 | try: 106 | return getattr(logging, level.upper()) 107 | except AttributeError: 108 | raise ValueError('Invalid log level: {}'.format(level)) 109 | else: 110 | raise TypeError( 111 | 'Log level must be int (0 ~ 50) or string,' 112 | 'but gat type: {}'.format(type(level))) 113 | 114 | 115 | def set_loglevel(level: Union[int, str, None] = None) -> None: 116 | """Set proper log-level. 117 | 118 | :arg Optional[int, str] level: Level to be set. If None, use proper log 119 | level from command line option. Default value is ``logging.INFO``. 120 | """ 121 | if level is not None: 122 | lv = level_to_int(level) 123 | elif config.logging: 124 | lv = level_to_int(config.logging) 125 | elif config.debug: 126 | lv = logging.DEBUG 127 | else: 128 | lv = logging.INFO 129 | root_logger.setLevel(lv) 130 | _log_handler.setLevel(lv) 131 | 132 | 133 | def parse_command_line() -> Namespace: 134 | """Parse command line options and set them to ``config``. 135 | 136 | This function skips unknown command line options. After parsing options, 137 | set log level and set options in ``tornado.options``. 138 | """ 139 | import tornado.options 140 | parser.parse_known_args(namespace=config) 141 | set_loglevel() # set new log level based on commanline option 142 | for k, v in vars(config).items(): 143 | if k.startswith('log'): 144 | tornado.options.options.__setattr__(k, v) 145 | return config 146 | 147 | 148 | parse_command_line() 149 | -------------------------------------------------------------------------------- /wdom/parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Parser base classes to parse HTML to Wdom objects.""" 5 | 6 | from xml.etree.ElementTree import HTML_EMPTY # type: ignore 7 | from html.parser import HTMLParser 8 | from typing import Any, Callable, List, Optional, Tuple, TYPE_CHECKING 9 | 10 | from wdom.node import Node, Text 11 | 12 | if TYPE_CHECKING: 13 | from wdom.document import Document # noqa: F401 14 | from wdom.node import ParentNode # noqa: F401 15 | 16 | _T_ElementFactory = Callable[[str, Optional[str], Optional[type], dict], Node] 17 | 18 | 19 | class FragmentParser(HTMLParser): 20 | """Parser class to parse HTML fragment strings. 21 | 22 | If unknown tag is found, ``default_class`` is used to generate noew. 23 | """ 24 | 25 | #: Class of unknown tag 26 | default_class = None # type: Optional[type] 27 | 28 | def __init__(self, *args: Any, 29 | element_factory: _T_ElementFactory = None, 30 | **kwargs: Any) -> None: 31 | """Initialize parser.""" 32 | super().__init__(*args, **kwargs) # type: ignore 33 | from wdom.node import DocumentFragment 34 | from wdom.document import create_element 35 | self.elm = DocumentFragment() # type: ParentNode 36 | self.root = self.elm 37 | self.current_tag = '' 38 | self.element_factory = element_factory or create_element 39 | 40 | def handle_starttag(self, tag: str, attr: List[Tuple[str, str]] 41 | ) -> None: # noqa: D102 42 | self.current_tag = tag 43 | attrs = dict(attr) 44 | elm = self.element_factory( 45 | tag, attrs.get('is'), self.default_class, attrs) 46 | if self.elm: 47 | self.elm.appendChild(elm) 48 | if tag not in HTML_EMPTY: 49 | self.elm = elm 50 | 51 | def handle_endtag(self, tag: str) -> None: # noqa: D102 52 | parent = self.elm.parentNode 53 | if parent is None: 54 | if self.elm is not self.root: 55 | raise ValueError('Parse Failed') 56 | else: 57 | self.elm = parent 58 | 59 | def handle_data(self, data: str) -> None: # noqa: D102 60 | if data: 61 | self.elm.appendChild(Text(data)) 62 | 63 | def handle_comment(self, comment: str) -> None: # noqa: D102 64 | from wdom.node import Comment 65 | self.elm.appendChild(Comment(comment)) 66 | 67 | 68 | def parse_html(html: str, parser: FragmentParser = None) -> Node: 69 | """Parse HTML fragment and return DocumentFragment object. 70 | 71 | DocumentFragment object has parsed Node objects as its child nodes. 72 | """ 73 | parser = parser or FragmentParser() 74 | parser.feed(html) 75 | return parser.root 76 | -------------------------------------------------------------------------------- /wdom/server/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Web server control functions.""" 5 | 6 | import os 7 | import json 8 | import logging 9 | import asyncio 10 | from typing import Any 11 | 12 | from tornado import autoreload 13 | 14 | from wdom.util import STATIC_DIR 15 | from wdom.options import config 16 | from wdom.server.base import exclude_patterns, open_browser, watch_dir 17 | from wdom.server import _tornado as module 18 | 19 | __all__ = ( 20 | 'add_static_path', 21 | 'exclude_patterns', 22 | 'get_app', 23 | 'start', 24 | 'start_server', 25 | 'stop_server', 26 | ) 27 | logger = logging.getLogger(__name__) 28 | _server = None 29 | server_config = module.server_config 30 | _msg_queue = [] 31 | 32 | 33 | def is_connected() -> bool: 34 | """Check if the current server has a client connection.""" 35 | return module.is_connected() 36 | 37 | 38 | def push_message(msg: dict) -> None: 39 | """Push message on the message queue.""" 40 | _msg_queue.append(msg) 41 | 42 | 43 | def send_message() -> None: 44 | """Send message via WS to all client connections.""" 45 | if not _msg_queue: 46 | return 47 | msg = json.dumps(_msg_queue) 48 | _msg_queue.clear() 49 | for conn in module.connections: 50 | conn.write_message(msg) 51 | 52 | 53 | def add_static_path(prefix: str, path: str, no_watch: bool = False) -> None: 54 | """Add directory to serve static files. 55 | 56 | First argument ``prefix`` is a URL prefix for the ``path``. ``path`` must 57 | be a directory. If ``no_watch`` is True, any change of the files in the 58 | path do not trigger restart if ``--autoreload`` is enabled. 59 | """ 60 | app = get_app() 61 | app.add_static_path(prefix, path) 62 | if not no_watch: 63 | watch_dir(path) 64 | 65 | 66 | def get_app() -> module.Application: 67 | """Get root web application object.""" 68 | return module.get_app() 69 | 70 | 71 | async def _message_loop() -> None: 72 | while True: 73 | send_message() 74 | await asyncio.sleep(config.message_wait) 75 | 76 | 77 | def start_server(address: str = None, port: int = None, 78 | check_time: int = 500, **kwargs: Any) -> module.HTTPServer: 79 | """Start web server on ``address:port``. 80 | 81 | Use wrapper function :func:`start` instead. 82 | 83 | :arg str address: address of the server [default: localhost]. 84 | :arg int port: tcp port of the server [default: 8888]. 85 | :arg int check_time: millisecondes to wait until reload browser when 86 | autoreload is enabled [default: 500]. 87 | """ 88 | # Add application's static files directory 89 | from wdom.document import get_document 90 | add_static_path('_static', STATIC_DIR) 91 | doc = get_document() 92 | if os.path.exists(doc.tempdir): 93 | add_static_path('tmp', doc.tempdir, no_watch=True) 94 | if doc._autoreload or config.autoreload or config.debug: 95 | autoreload.start(check_time=check_time) 96 | global _server 97 | _server = module.start_server(address=address, port=port, **kwargs) 98 | logger.info('Start server on {0}:{1:d}'.format( 99 | server_config['address'], server_config['port'])) 100 | 101 | # start messaging loop 102 | asyncio.ensure_future(_message_loop()) 103 | 104 | if config.open_browser: 105 | open_browser('http://{}:{}/'.format(server_config['address'], 106 | server_config['port']), 107 | config.browser) 108 | return _server 109 | 110 | 111 | def stop_server(server: module.HTTPServer = None) -> None: 112 | """Terminate web server.""" 113 | module.stop_server(server or _server) 114 | 115 | 116 | def start(**kwargs: Any) -> None: 117 | """Start web server. 118 | 119 | Run until ``Ctrl-c`` pressed, or if auto-shutdown is enabled, until when 120 | all browser windows are closed. 121 | 122 | This function accepts keyword areguments same as :func:`start_server` and 123 | all arguments passed to it. 124 | """ 125 | start_server(**kwargs) 126 | try: 127 | asyncio.get_event_loop().run_forever() 128 | except KeyboardInterrupt: 129 | stop_server() 130 | -------------------------------------------------------------------------------- /wdom/server/base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Base/Utility functions for server module.""" 5 | 6 | import sys 7 | import re 8 | import copy 9 | import pathlib 10 | import webbrowser 11 | from webbrowser import _browsers # type: ignore 12 | from typing import TYPE_CHECKING 13 | 14 | from tornado import autoreload 15 | 16 | from wdom.options import config 17 | 18 | if TYPE_CHECKING: 19 | from typing import List, Pattern # noqa 20 | 21 | exclude_patterns = [ 22 | r'node_modules', 23 | r'__pycache__', 24 | r'\..*', 25 | ] 26 | _exclude_patterns_re = [] # type: List[Pattern] 27 | _exclude_patterns_prev = [] # type: List[str] 28 | 29 | 30 | def _compile_exclude_patterns() -> None: 31 | global _exclude_patterns_re, _exclude_patterns_prev 32 | if _exclude_patterns_prev == exclude_patterns: 33 | return 34 | else: 35 | _exclude_patterns_prev = copy.copy(exclude_patterns) 36 | for pat in exclude_patterns: 37 | _exclude_patterns_re.append(re.compile(pat)) 38 | 39 | 40 | def _is_exclude(name: str) -> bool: 41 | return any(pat.match(name) for pat in _exclude_patterns_re) 42 | 43 | 44 | def _add_watch_path(path: pathlib.Path) -> None: 45 | if _is_exclude(path.name): 46 | return 47 | elif path.is_dir(): 48 | for f in path.iterdir(): 49 | _add_watch_path(f) 50 | elif path.is_file(): 51 | autoreload.watch(str(path)) 52 | 53 | 54 | def watch_dir(path: str) -> None: 55 | """Add ``path`` to watch for autoreload.""" 56 | _compile_exclude_patterns() 57 | if config.autoreload or config.debug: 58 | # Add files to watch for autoreload 59 | p = pathlib.Path(path) 60 | p.resolve() 61 | _add_watch_path(p) 62 | 63 | 64 | def open_browser(url: str, browser: str = None) -> None: 65 | """Open web browser.""" 66 | if '--open-browser' in sys.argv: 67 | # Remove open browser to prevent making new tab on autoreload 68 | sys.argv.remove('--open-browser') 69 | if browser is None: 70 | browser = config.browser 71 | if browser in _browsers: 72 | webbrowser.get(browser).open(url) 73 | else: 74 | webbrowser.open(url) 75 | -------------------------------------------------------------------------------- /wdom/server/handler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Event/Message handlers for web server.""" 5 | 6 | import json 7 | import logging 8 | from typing import Dict 9 | 10 | from wdom.event import Event, create_event, EventMsgDict 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | 15 | def log_handler(level: str, message: str) -> None: 16 | """Handle logs from client (browser).""" 17 | message = 'JS: ' + str(message) 18 | if level == 'error': 19 | logger.error(message) 20 | elif level == 'warn': 21 | logger.warning(message) 22 | elif level == 'info': 23 | logger.info(message) 24 | elif level == 'debug': 25 | logger.debug(message) 26 | 27 | 28 | def create_event_from_msg(msg: EventMsgDict) -> Event: 29 | """Create Event from dictionally (JSON message). 30 | 31 | Message format: 32 | { 33 | 'proto': 'event.__proto__.toString()', 34 | 'type': 'event type', 35 | 'currentTarget': { 36 | 'id': 'wdom_id of target node', 37 | ... (additional information), 38 | }, 39 | 'target': { 40 | 'id': 'wdom_id of target node', 41 | ... (additional information), 42 | }, 43 | ..., // event specific fields 44 | } 45 | """ 46 | return create_event(msg) 47 | 48 | 49 | def event_handler(msg: EventMsgDict) -> Event: 50 | """Handle events emitted on browser.""" 51 | e = create_event_from_msg(msg) 52 | if e.currentTarget is None: 53 | if e.type not in ['mount', 'unmount']: 54 | id = msg['currentTarget']['id'] 55 | logger.warning('No such element: wdom_id={}'.format(id)) 56 | return e 57 | e.currentTarget.on_event_pre(e) 58 | e.currentTarget.dispatchEvent(e) 59 | return e 60 | 61 | 62 | def response_handler(msg: Dict[str, str]) -> None: 63 | """Handle response sent by browser.""" 64 | from wdom.document import getElementByWdomId 65 | id = msg['id'] 66 | elm = getElementByWdomId(id) 67 | if elm: 68 | elm.on_response(msg) 69 | else: 70 | logger.warning('No such element: wdom_id={}'.format(id)) 71 | 72 | 73 | def on_websocket_message(message: str) -> None: 74 | """Handle messages from browser.""" 75 | msgs = json.loads(message) 76 | for msg in msgs: 77 | if not isinstance(msg, dict): 78 | logger.error('Invalid WS message format: {}'.format(message)) 79 | continue 80 | _type = msg.get('type') 81 | if _type == 'log': 82 | log_handler(msg['level'], msg['message']) 83 | elif _type == 'event': 84 | event_handler(msg['event']) 85 | elif _type == 'response': 86 | response_handler(msg) 87 | else: 88 | raise ValueError('Unkown message type: {}'.format(message)) 89 | -------------------------------------------------------------------------------- /wdom/themes/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | import os 6 | import re 7 | import logging 8 | 9 | from wdom.tag import * 10 | 11 | logger = logging.getLogger(__name__) 12 | curdir = os.path.dirname(os.path.abspath(__file__)) 13 | theme_list = sorted(set(re.sub(r'\.py[codx]?$', '', file) 14 | for file in os.listdir(curdir) 15 | if not file.startswith('_'))) 16 | 17 | # theme informations 18 | name = 'default' 19 | project_url = '' 20 | project_repository = '' 21 | license = '' 22 | license_url = '' 23 | 24 | # css/js/headers 25 | css_files = [] # type: List[str] 26 | js_files = [] # type: List[str] 27 | headers = [] # type: List[str] 28 | 29 | TextInput = NewTagClass('TextInput', 'input', Input, type_='text') 30 | CheckBox = NewTagClass('CheckBox', 'input', Input, type_='checkbox') 31 | RadioButton = NewTagClass('RadioButton', 'input', Input, type_='radio') 32 | 33 | # Building blocks 34 | Container = NewTagClass('Container', 'div', Div, is_='container') 35 | Wrapper = NewTagClass('Wrapper', 'div', Div, is_='wrapper') 36 | Row = NewTagClass('Row', 'div', Div, is_='row') 37 | FormGroup = NewTagClass('FormGroup', 'div', Div, is_='formgroup') 38 | FormOuter = NewTagClass('FormOuter', 'div', Div, is_='form-outer') 39 | FormInner = NewTagClass('FormInner', 'div', Div, is_='form-inner') 40 | FormItem = NewTagClass('FormItem', 'div', Div, is_='form-item') 41 | Col = NewTagClass('Col', 'div', Div, is_='col') 42 | Col1 = NewTagClass('Col1', 'div', Div, is_='col1') 43 | Col2 = NewTagClass('Col2', 'div', Div, is_='col2') 44 | Col3 = NewTagClass('Col3', 'div', Div, is_='col3') 45 | Col4 = NewTagClass('Col4', 'div', Div, is_='col4') 46 | Col5 = NewTagClass('Col5', 'div', Div, is_='col5') 47 | Col6 = NewTagClass('Col6', 'div', Div, is_='col6') 48 | Col7 = NewTagClass('Col7', 'div', Div, is_='col7') 49 | Col8 = NewTagClass('Col8', 'div', Div, is_='col8') 50 | Col9 = NewTagClass('Col9', 'div', Div, is_='col9') 51 | Col10 = NewTagClass('Col10', 'div', Div, is_='col10') 52 | Col11 = NewTagClass('Col11', 'div', Div, is_='col11') 53 | Col12 = NewTagClass('Col12', 'div', Div, is_='col12') 54 | 55 | # Some css updates 56 | DefaultButton = NewTagClass('DefaultButton', 'button', Button, is_='default-button') 57 | PrimaryButton = NewTagClass('PrimaryButton', 'button', Button, is_='primary-button') 58 | SecondaryButton = NewTagClass('SecondaryButton', 'button', Button, is_='secondary-button') 59 | SuccessButton = NewTagClass('SuccessButton', 'button', Button, is_='success-button') 60 | InfoButton = NewTagClass('InfoButton', 'button', Button, is_='info-button') 61 | WarningButton = NewTagClass('WarningButton', 'button', Button, is_='warning-button') 62 | DangerButton = NewTagClass('DangerButton', 'button', Button, is_='danger-button') 63 | ErrorButton = NewTagClass('ErrorButton', 'button', Button, is_='error-button') 64 | LinkButton = NewTagClass('LinkButton', 'button', Button, is_='link-button') 65 | 66 | extended_classes = [ 67 | Container, 68 | Wrapper, 69 | Row, 70 | FormGroup, 71 | FormOuter, 72 | FormInner, 73 | FormItem, 74 | Col, 75 | Col1, 76 | Col2, 77 | Col3, 78 | Col4, 79 | Col5, 80 | Col6, 81 | Col7, 82 | Col8, 83 | Col9, 84 | Col10, 85 | Col11, 86 | Col12, 87 | DefaultButton, 88 | PrimaryButton, 89 | SecondaryButton, 90 | SuccessButton, 91 | InfoButton, 92 | WarningButton, 93 | DangerButton, 94 | ErrorButton, 95 | LinkButton, 96 | ] 97 | -------------------------------------------------------------------------------- /wdom/themes/bagpakk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Bagpakk' 9 | project_url = 'http://brutaldesign.github.io/bagpakk/' 10 | project_repository = 'https://github.com/brutaldesign/bagpakk/' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/brutaldesign/bagpakk/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '_static/css/bagpakk.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', 'a', class_='button-alt', is_='button') 19 | DefaultButton = NewTag('DefaultButton', 'a', class_='button-alt', is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'a', class_='button', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'a', class_='button-alt', is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'a', class_='button', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'a', class_='button-alt', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'a', class_='button', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'a', class_='button', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'a', class_='button', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'a', class_='button-alt', is_='link-button') 28 | 29 | Col1 = NewTag('Col1', 'div', Col, class_='col-1', is_='col1') 30 | Col2 = NewTag('Col2', 'div', Col, class_='col-2', is_='col2') 31 | Col3 = NewTag('Col3', 'div', Col, class_='col-3', is_='col3') 32 | Col4 = NewTag('Col4', 'div', Col, class_='col-4', is_='col4') 33 | Col5 = NewTag('Col5', 'div', Col, class_='col-5', is_='col5') 34 | Col6 = NewTag('Col6', 'div', Col, class_='col-6', is_='col6') 35 | Col7 = NewTag('Col7', 'div', Col, class_='col-7', is_='col7') 36 | Col8 = NewTag('Col8', 'div', Col, class_='col-8', is_='col8') 37 | Col9 = NewTag('Col9', 'div', Col, class_='col-9', is_='col9') 38 | Col10 = NewTag('Col10', 'div', Col, class_='col-10', is_='col10') 39 | Col11 = NewTag('Col11', 'div', Col, class_='col-11', is_='col11') 40 | Col12 = NewTag('Col12', 'div', Col, class_='col-12', is_='col12') 41 | 42 | extended_classes = [ 43 | Button, 44 | DefaultButton, 45 | PrimaryButton, 46 | SecondaryButton, 47 | SuccessButton, 48 | InfoButton, 49 | WarningButton, 50 | DangerButton, 51 | ErrorButton, 52 | LinkButton, 53 | Col1, 54 | Col2, 55 | Col3, 56 | Col4, 57 | Col5, 58 | Col6, 59 | Col7, 60 | Col8, 61 | Col9, 62 | Col10, 63 | Col11, 64 | Col12, 65 | ] 66 | -------------------------------------------------------------------------------- /wdom/themes/baseguide.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Baseguide' 9 | project_url = 'http://basegui.de/' 10 | project_repository = 'https://github.com/slavanga/baseguide' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/slavanga/baseguide/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '_static/css/baseguide.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='btn', is_='btn') 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='btn-default', is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='btn-primary', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='btn-secondary', is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='btn-success', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, class_='btn-info', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', Button, class_='btn-warning', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'button', Button, class_='btn-danger', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='btn-danger', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, class_='btn-link', is_='link-button') 28 | 29 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='form-group') 30 | Input = NewTag('Input', 'input', Input, class_='form-control') 31 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-control') 32 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-control') 33 | Select = NewTag('Select', 'select', Select, class_='form-control') 34 | 35 | Table = NewTag('Table', 'table', Table, class_='table') 36 | 37 | Container = NewTag('Container', 'div', Container, class_='container') 38 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 39 | Row = NewTag('Row', 'div', Row, class_='row') 40 | 41 | Col = NewTag('Col', 'div', Col, class_='col') 42 | Col1 = NewTag('Col1', 'div', Col1, class_='col col-xs-1 col-sm-1 col-md-1 col-lg-1') 43 | Col2 = NewTag('Col2', 'div', Col2, class_='col col-xs-2 col-sm-2 col-md-2 col-lg-2') 44 | Col3 = NewTag('Col3', 'div', Col3, class_='col col-xs-3 col-sm-3 col-md-3 col-lg-3') 45 | Col4 = NewTag('Col4', 'div', Col4, class_='col col-xs-4 col-sm-4 col-md-4 col-lg-4') 46 | Col5 = NewTag('Col5', 'div', Col5, class_='col col-xs-5 col-sm-5 col-md-5 col-lg-5') 47 | Col6 = NewTag('Col6', 'div', Col6, class_='col col-xs-6 col-sm-6 col-md-6 col-lg-6') 48 | Col7 = NewTag('Col7', 'div', Col7, class_='col col-xs-7 col-sm-7 col-md-7 col-lg-7') 49 | Col8 = NewTag('Col8', 'div', Col8, class_='col col-xs-8 col-sm-8 col-md-8 col-lg-8') 50 | Col9 = NewTag('Col9', 'div', Col9, class_='col col-xs-9 col-sm-9 col-md-9 col-lg-9') 51 | Col10 = NewTag('Col10', 'div', Col10, class_='col col-xs-10 col-sm-10 col-md-10 col-lg-10') 52 | Col11 = NewTag('Col11', 'div', Col11, class_='col col-xs-11 col-sm-11 col-md-11 col-lg-11') 53 | Col12 = NewTag('Col12', 'div', Col12, class_='col col-xs-12 col-sm-12 col-md-12 col-lg-12') 54 | 55 | extended_classes = [ 56 | Button, 57 | DefaultButton, 58 | PrimaryButton, 59 | SecondaryButton, 60 | SuccessButton, 61 | InfoButton, 62 | WarningButton, 63 | DangerButton, 64 | ErrorButton, 65 | LinkButton, 66 | FormGroup, 67 | Input, 68 | TextInput, 69 | Textarea, 70 | Select, 71 | Table, 72 | Container, 73 | Wrapper, 74 | Row, 75 | Col, 76 | Col1, 77 | Col2, 78 | Col3, 79 | Col4, 80 | Col5, 81 | Col6, 82 | Col7, 83 | Col8, 84 | Col9, 85 | Col10, 86 | Col11, 87 | Col12, 88 | ] 89 | -------------------------------------------------------------------------------- /wdom/themes/bijou.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Bijou' 9 | project_url = 'http://andhart.github.io/bijou/' 10 | project_repository = 'https://github.com/andhart/bijou' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/andhart/bijou/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '_static/css/bijou.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='button small') 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='primary', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, class_='success', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', Button, class_='danger', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'button', Button, class_='danger', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='danger', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, is_='link-button') 28 | 29 | Table = NewTag('Table', 'table', Table, class_='table') 30 | 31 | Row = NewTag('Row', 'div', Row, class_='row') 32 | Col = NewTag('Col', 'div', Col, class_='span') 33 | Col1 = NewTag('Col1', 'div', (Col1, Col), class_='one') 34 | Col2 = NewTag('Col2', 'div', (Col2, Col), class_='two') 35 | Col3 = NewTag('Col3', 'div', (Col3, Col), class_='three') 36 | Col4 = NewTag('Col4', 'div', (Col4, Col), class_='four') 37 | Col5 = NewTag('Col5', 'div', (Col5, Col), class_='five') 38 | Col6 = NewTag('Col6', 'div', (Col6, Col), class_='six') 39 | Col7 = NewTag('Col7', 'div', (Col7, Col), class_='seven') 40 | Col8 = NewTag('Col8', 'div', (Col8, Col), class_='eight') 41 | Col9 = NewTag('Col9', 'div', (Col9, Col), class_='nine') 42 | Col10 = NewTag('Col10', 'div', (Col10, Col), class_='ten') 43 | Col11 = NewTag('Col11', 'div', (Col11, Col), class_='eleven') 44 | 45 | extended_classes = [ 46 | Button, 47 | DefaultButton, 48 | PrimaryButton, 49 | SuccessButton, 50 | InfoButton, 51 | WarningButton, 52 | DangerButton, 53 | ErrorButton, 54 | LinkButton, 55 | Table, 56 | Row, 57 | Col1, 58 | Col2, 59 | Col3, 60 | Col4, 61 | Col5, 62 | Col6, 63 | Col7, 64 | Col8, 65 | Col9, 66 | Col10, 67 | Col11, 68 | ] 69 | -------------------------------------------------------------------------------- /wdom/themes/blaze.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Blaze' 9 | project_url = 'http://blazecss.com/' 10 | project_repository = 'https://github.com/BlazeCSS/blaze' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/BlazeCSS/blaze/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | 'https://unpkg.com/blaze', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='c-button') 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='c-button--primary', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='c-button--secondary', is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='c-button--success', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, class_='c-button--primary', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', Button, class_='c-button--secondary', is_='warining-button') 25 | DangerButton = NewTag('DangerButton', 'button', Button, class_='c-button--error', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='c-button--error', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, is_='c-link-button') 28 | 29 | Input = NewTag('Input', 'input', Input, class_='c-field') 30 | TextInput = NewTag('TextInput', 'input', TextInput, class_='c-field') 31 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='c-field') 32 | Select = NewTag('Select', 'select', Select, class_='c-choice') 33 | 34 | Ul = NewTag('Ul', 'ul', Ul, class_='c-list') 35 | Ol = NewTag('Ol', 'ol', Ol, class_='c-list--ordered') 36 | Li = NewTag('Li', 'li', Li, class_='c-list__item') 37 | 38 | Table = NewTag('Table', 'table', Table, class_='c-table') 39 | Tr = NewTag('Tr', 'tr', Tr, class_='c-table__row') 40 | Th = NewTag('Th', 'th', Th, class_='c-table__cell') 41 | Td = NewTag('Td', 'td', Td, class_='c-table__cell') 42 | 43 | H1 = NewTag('H1', 'div', H1, class_='c-heading c-heading--super', is_='h1') 44 | H2 = NewTag('H2', 'div', H2, class_='c-heading c-heading--xlarge', is_='h1') 45 | H3 = NewTag('H3', 'div', H3, class_='c-heading c-heading--large', is_='h1') 46 | H4 = NewTag('H4', 'div', H4, class_='c-heading c-heading--medium', is_='h1') 47 | H5 = NewTag('H5', 'div', H5, class_='c-heading c-heading--small', is_='h1') 48 | H6 = NewTag('H6', 'div', H6, class_='c-heading c-heading--xsmall', is_='h1') 49 | 50 | Row = NewTag('Row', 'div', Row, class_='o-gird') 51 | Col = NewTag('Col', 'div', Col, class_='o-grid__cell') 52 | Col1 = NewTag('Col1', 'div', Col, class_='o-grid__cell--width-10', is_='col1') 53 | Col2 = NewTag('Col2', 'div', Col, class_='o-grid__cell--width-15', is_='col2') 54 | Col3 = NewTag('Col3', 'div', Col, class_='o-grid__cell--width-25', is_='col3') 55 | Col4 = NewTag('Col4', 'div', Col, class_='o-grid__cell--width-33', is_='col4') 56 | Col5 = NewTag('Col5', 'div', Col, class_='o-grid__cell--width-40', is_='col5') 57 | Col6 = NewTag('Col6', 'div', Col, class_='o-grid__cell--width-50', is_='col6') 58 | Col7 = NewTag('Col7', 'div', Col, class_='o-grid__cell--width-60', is_='col7') 59 | Col8 = NewTag('Col8', 'div', Col, class_='o-grid__cell--width-66', is_='col8') 60 | Col9 = NewTag('Col9', 'div', Col, class_='o-grid__cell--width-75', is_='col9') 61 | Col10 = NewTag('Col10', 'div', Col, class_='o-grid__cell--width-85', is_='col10') 62 | Col11 = NewTag('Col11', 'div', Col, class_='o-grid__cell--width-90', is_='col11') 63 | Col12 = NewTag('Col12', 'div', Col, class_='o-grid__cell--width-100', is_='col12') 64 | 65 | extended_classes = [ 66 | Button, 67 | DefaultButton, 68 | PrimaryButton, 69 | SecondaryButton, 70 | SuccessButton, 71 | InfoButton, 72 | WarningButton, 73 | DangerButton, 74 | ErrorButton, 75 | LinkButton, 76 | Input, 77 | TextInput, 78 | Textarea, 79 | Select, 80 | Ul, 81 | Ol, 82 | Li, 83 | Table, 84 | Tr, 85 | Th, 86 | Td, 87 | H1, 88 | H2, 89 | H3, 90 | H4, 91 | H5, 92 | H6, 93 | Row, 94 | Col, 95 | Col1, 96 | Col2, 97 | Col3, 98 | Col4, 99 | Col5, 100 | Col6, 101 | Col7, 102 | Col8, 103 | Col9, 104 | Col10, 105 | Col11, 106 | ] 107 | -------------------------------------------------------------------------------- /wdom/themes/bootstrap3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Bootstrap3' 9 | project_url = 'http://getbootstrap.com/' 10 | project_repository = 'https://github.com/twbs/bootstrap' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/twbs/bootstrap/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css', 16 | ] 17 | 18 | js_files = [ 19 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', 20 | '//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js', 21 | ] 22 | 23 | headers = [] 24 | 25 | Button = NewTag('Button', 'button', bases=Button, class_='btn') 26 | # Inherit Button class defined here, to inherit 'btn' class 27 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='btn-default', is_='default-button') 28 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='btn-primary', is_='primary-button') 29 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='btn-secondary', is_='secondary-button') 30 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='btn-success', is_='success-button') 31 | InfoButton = NewTag('InfoButton', 'button', Button, class_='btn-info', is_='info-button') 32 | WarningButton = NewTag('WarningButton', 'button', Button, class_='btn-warning', is_='warning-button') 33 | DangerButton = NewTag('DangerButton', 'button', Button, class_='btn-danger', is_='danger-button') 34 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='btn-danger', is_='error-button') 35 | LinkButton = NewTag('LinkButton', 'button', Button, class_='btn-link', is_='link-button') 36 | 37 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='form-group') 38 | Input = NewTag('Input', 'input', Input, class_='form-control') 39 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-control') 40 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-control') 41 | Select = NewTag('Select', 'select', Select, class_='form-control') 42 | 43 | Table = NewTag('Table', 'table', Table, class_='table') 44 | 45 | Container = NewTag('Container', 'div', Container, class_='container') 46 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 47 | Row = NewTag('Row', 'div', Row, class_='row') 48 | 49 | Col1 = NewTag('Col1', 'div', Col1, class_='col-xs-1 col-sm-1 col-md-1 col-lg-1') 50 | Col2 = NewTag('Col2', 'div', Col2, class_='col-xs-2 col-sm-2 col-md-2 col-lg-2') 51 | Col3 = NewTag('Col3', 'div', Col3, class_='col-xs-3 col-sm-3 col-md-3 col-lg-3') 52 | Col4 = NewTag('Col4', 'div', Col4, class_='col-xs-4 col-sm-4 col-md-4 col-lg-4') 53 | Col5 = NewTag('Col5', 'div', Col5, class_='col-xs-5 col-sm-5 col-md-5 col-lg-5') 54 | Col6 = NewTag('Col6', 'div', Col6, class_='col-xs-6 col-sm-6 col-md-6 col-lg-6') 55 | Col7 = NewTag('Col7', 'div', Col7, class_='col-xs-7 col-sm-7 col-md-7 col-lg-7') 56 | Col8 = NewTag('Col8', 'div', Col8, class_='col-xs-8 col-sm-8 col-md-8 col-lg-8') 57 | Col9 = NewTag('Col9', 'div', Col9, class_='col-xs-9 col-sm-9 col-md-9 col-lg-9') 58 | Col10 = NewTag('Col10', 'div', Col10, class_='col-xs-10 col-sm-10 col-md-10 col-lg-10') 59 | Col11 = NewTag('Col11', 'div', Col11, class_='col-xs-11 col-sm-11 col-md-11 col-lg-11') 60 | 61 | extended_classes = [ 62 | Button, 63 | DefaultButton, 64 | PrimaryButton, 65 | SecondaryButton, 66 | SuccessButton, 67 | InfoButton, 68 | WarningButton, 69 | DangerButton, 70 | ErrorButton, 71 | LinkButton, 72 | FormGroup, 73 | Input, 74 | TextInput, 75 | Textarea, 76 | Select, 77 | Table, 78 | Container, 79 | Wrapper, 80 | Row, 81 | Col1, 82 | Col2, 83 | Col3, 84 | Col4, 85 | Col5, 86 | Col6, 87 | Col7, 88 | Col8, 89 | Col9, 90 | Col10, 91 | Col11, 92 | ] 93 | -------------------------------------------------------------------------------- /wdom/themes/bootstrap4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Bootstrap4' 9 | project_url = 'http://getbootstrap.com/' 10 | project_repository = 'https://github.com/twbs/bootstrap' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/twbs/bootstrap/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css', 16 | ] 17 | 18 | js_files = [ 19 | '//code.jquery.com/jquery-3.2.1.slim.min.js', 20 | '//cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js', 21 | '//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js', 22 | ] 23 | 24 | headers = [] 25 | 26 | Button = NewTag('Button', 'button', bases=Button, class_='btn') 27 | # Inherit Button class defined here, to inherit 'btn' class 28 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='btn-default', is_='default-button') 29 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='btn-primary', is_='primary-button') 30 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='btn-secondary', is_='secondary-button') 31 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='btn-success', is_='success-button') 32 | InfoButton = NewTag('InfoButton', 'button', Button, class_='btn-info', is_='info-button') 33 | WarningButton = NewTag('WarningButton', 'button', Button, class_='btn-warning', is_='warning-button') 34 | DangerButton = NewTag('DangerButton', 'button', Button, class_='btn-danger', is_='danger-button') 35 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='btn-danger', is_='error-button') 36 | LinkButton = NewTag('LinkButton', 'button', Button, class_='btn-link', is_='link-button') 37 | 38 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='form-group') 39 | Input = NewTag('Input', 'input', Input, class_='form-control') 40 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-control') 41 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-control') 42 | Select = NewTag('Select', 'select', Select, class_='form-control') 43 | 44 | Table = NewTag('Table', 'table', Table, class_='table') 45 | 46 | Container = NewTag('Container', 'div', Container, class_='container') 47 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 48 | Row = NewTag('Row', 'div', Row, class_='row') 49 | Col = NewTag('Col', 'div', Col, class_='col') 50 | Col1 = NewTag('Col1', 'div', Col1, class_='col-1 col-sm-1 col-md-1 col-lg-1 col-xl-1') 51 | Col2 = NewTag('Col2', 'div', Col2, class_='col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2') 52 | Col3 = NewTag('Col3', 'div', Col3, class_='col-3 col-sm-3 col-md-3 col-lg-3 col-xl-3') 53 | Col4 = NewTag('Col4', 'div', Col4, class_='col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4') 54 | Col5 = NewTag('Col5', 'div', Col5, class_='col-5 col-sm-5 col-md-5 col-lg-5 col-xl-5') 55 | Col6 = NewTag('Col6', 'div', Col6, class_='col-6 col-sm-6 col-md-6 col-lg-6 col-xl-6') 56 | Col7 = NewTag('Col7', 'div', Col7, class_='col-7 col-sm-7 col-md-7 col-lg-7 col-xl-7') 57 | Col8 = NewTag('Col8', 'div', Col8, class_='col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8') 58 | Col9 = NewTag('Col9', 'div', Col9, class_='col-9 col-sm-9 col-md-9 col-lg-9 col-xl-9') 59 | Col10 = NewTag('Col10', 'div', Col10, class_='col-10 col-sm-10 col-md-10 col-lg-10 col-xl-10') 60 | Col11 = NewTag('Col11', 'div', Col11, class_='col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11') 61 | Col12 = NewTag('Col12', 'div', Col12, class_='col-auto col-sm-auto col-md-auto col-lg-auto col-xl-auto') 62 | 63 | extended_classes = [ 64 | Button, 65 | DefaultButton, 66 | PrimaryButton, 67 | SecondaryButton, 68 | SuccessButton, 69 | InfoButton, 70 | WarningButton, 71 | DangerButton, 72 | ErrorButton, 73 | LinkButton, 74 | FormGroup, 75 | Input, 76 | TextInput, 77 | Textarea, 78 | Select, 79 | Table, 80 | Container, 81 | Wrapper, 82 | Row, 83 | Col1, 84 | Col2, 85 | Col3, 86 | Col4, 87 | Col5, 88 | Col6, 89 | Col7, 90 | Col8, 91 | Col9, 92 | Col10, 93 | Col11, 94 | ] 95 | -------------------------------------------------------------------------------- /wdom/themes/bulma.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Bulma' 9 | project_url = 'http://bulma.io/' 10 | project_repository = 'https://github.com/jgthms/bulma/' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/jgthms/bulma/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//cdnjs.cloudflare.com/ajax/libs/bulma/0.0.20/css/bulma.min.css', 16 | ] 17 | 18 | js_files = [] 19 | headers = [] 20 | 21 | Button = NewTag('Button', bases=Button, class_='button') 22 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 23 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='is-primary', is_='primary-button') 24 | SecondaryButton = NewTag('SecondaryButton', 'button', PrimaryButton, class_='is-outlined', is_='secondary-button') 25 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='is-success', is_='success-button') 26 | InfoButton = NewTag('InfoButton', 'button', Button, class_='is-info', is_='info-button') 27 | WarningButton = NewTag('WarningButton', 'button', Button, class_='is-warning', is_='warning-button') 28 | DangerButton = NewTag('DangerButton', 'button', Button, class_='is-danger', is_='danger-button') 29 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='is-danger', is_='error-button') 30 | LinkButton = NewTag('LinkButton', 'button', Button, class_='is-link', is_='link-button') 31 | 32 | Input = NewTag('Input', 'input', Input) 33 | TextInput = NewTag('Input', 'input', Input, type_='text', class_='input') 34 | CheckBox = NewTag('Input', 'input', Input, type_='checkbox', class_='checkbox') 35 | RadioButton = NewTag('Input', 'input', Input, type_='radio', class_='radio') 36 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='textarea') 37 | 38 | class Select(NestedTag): 39 | tag = 'span' 40 | class_ = 'select' 41 | inner_tag_class = Select 42 | is_ = 'select' 43 | def __init__(self, *args, **kwargs): 44 | super().__init__(*args, **kwargs) 45 | self._inner_element.addEventListener('change', self.dispatchEvent) 46 | self._inner_element.addEventListener('click', self.dispatchEvent) 47 | 48 | Table = NewTag('Table', 'table', Table, class_='table') 49 | 50 | H1 = NewTag('H1', 'h1', H1, class_='title is-1') 51 | H2 = NewTag('H2', 'h2', H2, class_='title is-2') 52 | H3 = NewTag('H3', 'h3', H3, class_='title is-3') 53 | H4 = NewTag('H4', 'h4', H4, class_='title is-4') 54 | H5 = NewTag('H5', 'h5', H5, class_='title is-5') 55 | H6 = NewTag('H6', 'h6', H6, class_='title is-6') 56 | 57 | Container = NewTag('Container', 'div', Container, class_='content') 58 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='content') 59 | Row = NewTag('Row', 'div', Row, class_='columns') 60 | 61 | Col = NewTag('Col', 'div', Col, class_='column') 62 | Col1 = NewTag('Col1', 'div', Col, class_='is-1', is_='col1') 63 | Col2 = NewTag('Col2', 'div', Col, class_='is-2', is_='col2') 64 | Col3 = NewTag('Col3', 'div', Col, class_='is-3', is_='col3') 65 | Col4 = NewTag('Col4', 'div', Col, class_='is-4', is_='col4') 66 | Col5 = NewTag('Col5', 'div', Col, class_='is-5', is_='col5') 67 | Col6 = NewTag('Col6', 'div', Col, class_='is-6', is_='col6') 68 | Col7 = NewTag('Col7', 'div', Col, class_='is-7', is_='col7') 69 | Col8 = NewTag('Col8', 'div', Col, class_='is-8', is_='col8') 70 | Col9 = NewTag('Col9', 'div', Col, class_='is-9', is_='col9') 71 | Col10 = NewTag('Col10', 'div', Col, class_='is-10', is_='col10') 72 | Col11 = NewTag('Col11', 'div', Col, class_='is-11', is_='col11') 73 | Col12 = NewTag('Col12', 'div', Col, class_='is-12', is_='col12') 74 | 75 | extended_classes = [ 76 | Button, 77 | DefaultButton, 78 | PrimaryButton, 79 | SecondaryButton, 80 | SuccessButton, 81 | InfoButton, 82 | WarningButton, 83 | DangerButton, 84 | ErrorButton, 85 | LinkButton, 86 | Input, 87 | TextInput, 88 | CheckBox, 89 | RadioButton, 90 | Textarea, 91 | Select, 92 | Table, 93 | H1, 94 | H2, 95 | H3, 96 | H4, 97 | H5, 98 | H6, 99 | Container, 100 | Wrapper, 101 | Row, 102 | Col, 103 | Col1, 104 | Col2, 105 | Col3, 106 | Col4, 107 | Col5, 108 | Col6, 109 | Col7, 110 | Col8, 111 | Col9, 112 | Col10, 113 | Col11, 114 | Col12, 115 | ] 116 | -------------------------------------------------------------------------------- /wdom/themes/concise.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Concise' 9 | project_url = 'http://http://concisecss.com/' 10 | project_repository = 'https://github.com/ConciseCSS/concise.css' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/ConciseCSS/concise.css/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//cdn.concisecss.com/v3.4.0/concise.min.css', 16 | ] 17 | js_files = [] 18 | headers = [] 19 | 20 | DefaultButton = NewTag('DefaultButton', 'button', DefaultButton) 21 | PrimaryButton = NewTag('PrimaryButton', 'button', PrimaryButton, class_='bg--primary') 22 | SecondaryButton = NewTag('SecondaryButton', 'button', SecondaryButton, class_='bg--success') 23 | SuccessButton = NewTag('SuccessButton', 'button', SuccessButton, class_='bg--success') 24 | InfoButton = NewTag('InfoButton', 'button', InfoButton, class_='button--flat') 25 | WarningButton = NewTag('WarningButton', 'button', WarningButton, class_='bg--warning') 26 | DangerButton = NewTag('DangerButton', 'button', DangerButton, class_='bg--error') 27 | ErrorButton = NewTag('ErrorButton', 'button', ErrorButton, class_='bg--error') 28 | LinkButton = NewTag('LinkButton', 'button', LinkButton, class_='button--flat') 29 | 30 | Container = NewTag('Container', 'div', Container, class_='container') 31 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 32 | Row = NewTag('Row', 'div', Row, class_='row') 33 | 34 | class Col(Div): 35 | column = None 36 | is_ = 'col' 37 | def __init__(self, *args, **kwargs): 38 | super().__init__(*args, **kwargs) 39 | if self.column: 40 | self.setAttribute('column', str(self.column)) 41 | 42 | Col1 = NewTag('Col1', 'div', Col, column=1, is_='col1') 43 | Col2 = NewTag('Col2', 'div', Col, column=2, is_='col2') 44 | Col3 = NewTag('Col3', 'div', Col, column=3, is_='col3') 45 | Col4 = NewTag('Col4', 'div', Col, column=4, is_='col4') 46 | Col5 = NewTag('Col5', 'div', Col, column=5, is_='col5') 47 | Col6 = NewTag('Col6', 'div', Col, column=6, is_='col6') 48 | Col7 = NewTag('Col7', 'div', Col, column=7, is_='col7') 49 | Col8 = NewTag('Col8', 'div', Col, column=8, is_='col8') 50 | Col9 = NewTag('Col9', 'div', Col, column=9, is_='col9') 51 | Col10 = NewTag('Col10', 'div', Col, column=10, is_='col10') 52 | Col11 = NewTag('Col11', 'div', Col, column=11, is_='col11') 53 | Col12 = NewTag('Col12', 'div', Col, column=12, is_='col12') 54 | 55 | extended_classes = [ 56 | Button, 57 | DefaultButton, 58 | PrimaryButton, 59 | SecondaryButton, 60 | SuccessButton, 61 | InfoButton, 62 | WarningButton, 63 | DangerButton, 64 | ErrorButton, 65 | LinkButton, 66 | Container, 67 | Wrapper, 68 | Row, 69 | Col, 70 | Col1, 71 | Col2, 72 | Col3, 73 | Col4, 74 | Col5, 75 | Col6, 76 | Col7, 77 | Col8, 78 | Col9, 79 | Col10, 80 | Col11, 81 | Col12, 82 | ] 83 | -------------------------------------------------------------------------------- /wdom/themes/default.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | 6 | """Keep this module for backward compatibility.""" 7 | 8 | import re 9 | 10 | from wdom.options import config 11 | from wdom.themes import logger, theme_list 12 | 13 | theme = config.theme 14 | 15 | if theme: 16 | theme = re.sub(r'\.py[codx]?$', '', theme) 17 | if theme in theme_list: 18 | # import theme 19 | logger.info('Use theme: {}'.format(theme)) 20 | exec('from wdom.themes.{} import *'.format(theme)) 21 | else: 22 | logger.warning( 23 | 'Unknown theme "{}" was specified. Use default.'.format(theme)) 24 | # Remove duplicated module name (*.py and *.pyc may exists) 25 | logger.warning( 26 | 'Available themes: {}'.format(', '.join(theme_list))) 27 | from wdom.themes import * 28 | name = 'default' 29 | else: 30 | logger.info('No theme specified. Use default theme.') 31 | from wdom.themes import * 32 | name = 'default' 33 | -------------------------------------------------------------------------------- /wdom/themes/foundation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Foundation' 9 | project_url = 'http://foundation.zurb.com/' 10 | project_repository = 'https://github.com/zurb/foundation-sites' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/zurb/foundation-sites/blob/develop/LICENSE' 13 | 14 | css_files = [ 15 | '//cdn.jsdelivr.net/foundation/6.2.1/foundation.min.css', 16 | ] 17 | 18 | js_files = [ 19 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', 20 | '//cdn.jsdelivr.net/foundation/6.2.1/foundation.min.js', 21 | ] 22 | 23 | headers = [] 24 | 25 | Button = NewTag('Button', bases=Button, class_='button') 26 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='hollow secondary', is_='default-button') 27 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, is_='primary-button') 28 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='secondary', is_='secondary-button') 29 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success', is_='success-button') 30 | InfoButton = NewTag('InfoButton', 'button', Button, class_='success hollow', is_='info-button') 31 | WarningButton = NewTag('WarningButton', 'button', Button, class_='warning', is_='warning-button') 32 | DangerButton = NewTag('DangerButton', 'button', Button, class_='alert', is_='danger-button') 33 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='alert', is_='error-button') 34 | LinkButton = NewTag('LinkButton', 'button', Button, class_='hollow', is_='link-button') 35 | 36 | Row = NewTag('Row', 'div', Row, class_='row') 37 | Col = NewTag('Col', 'div', Col, class_='columns') 38 | Col1 = NewTag('Col1', 'div', Col, class_='small-1 medium-1 large-1', is_='col1') 39 | Col2 = NewTag('Col2', 'div', Col, class_='small-2 medium-2 large-2', is_='col2') 40 | Col3 = NewTag('Col3', 'div', Col, class_='small-3 medium-3 large-3', is_='col3') 41 | Col4 = NewTag('Col4', 'div', Col, class_='small-4 medium-4 large-4', is_='col4') 42 | Col5 = NewTag('Col5', 'div', Col, class_='small-5 medium-5 large-5', is_='col5') 43 | Col6 = NewTag('Col6', 'div', Col, class_='small-6 medium-6 large-6', is_='col6') 44 | Col7 = NewTag('Col7', 'div', Col, class_='small-7 medium-7 large-7', is_='col7') 45 | Col8 = NewTag('Col8', 'div', Col, class_='small-8 medium-8 large-8', is_='col8') 46 | Col9 = NewTag('Col9', 'div', Col, class_='small-9 medium-9 large-9', is_='col9') 47 | Col10 = NewTag('Col10', 'div', Col, class_='small-10 medium-10 large-10', is_='col10') 48 | Col11 = NewTag('Col11', 'div', Col, class_='small-11 medium-11 large-11', is_='col11') 49 | Col12 = NewTag('Col12', 'div', Col, class_='small-12 medium-12 large-12', is_='col12') 50 | 51 | extended_classes = [ 52 | Button, 53 | DefaultButton, 54 | PrimaryButton, 55 | SecondaryButton, 56 | SuccessButton, 57 | InfoButton, 58 | WarningButton, 59 | DangerButton, 60 | ErrorButton, 61 | LinkButton, 62 | Row, 63 | Col, 64 | Col1, 65 | Col2, 66 | Col3, 67 | Col4, 68 | Col5, 69 | Col6, 70 | Col7, 71 | Col8, 72 | Col9, 73 | Col10, 74 | Col11, 75 | Col12, 76 | ] 77 | -------------------------------------------------------------------------------- /wdom/themes/furtive.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Furtive' 9 | project_url = 'http://furtive.co/' 10 | project_repository = 'https://github.com/johnotander/furtive' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/johnotander/furtive/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//cdnjs.cloudflare.com/ajax/libs/furtive/2.2.3/furtive.css', 16 | ] 17 | 18 | Button = NewTag('Button', 'a', Button, class_='btn', is_='button') 19 | DefaultButton = NewTag('DefaultButton', 'a', Button, is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'a', Button, class_='btn--blue', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'a', Button, is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'a', Button, class_='btn--green', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'a', Button, class_='btn--blue', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'a', Button, class_='btn--red', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'a', Button, class_='btn--red', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'a', Button, class_='btn--red', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'a', Button, class_='btn--link', is_='link-button') 28 | 29 | Container = NewTag('Container', 'div', Container, class_='grd') 30 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='grd') 31 | Row = NewTag('Row', 'div', Row, class_='grd-row') 32 | # Why 6 columns... 33 | Col = NewTag('Col', 'div', Col) 34 | Col1 = NewTag('Col1', 'div', Col1, class_='grd-row-col-1-6') 35 | Col2 = NewTag('Col2', 'div', Col2, class_='grd-row-col-1-6') 36 | Col3 = NewTag('Col3', 'div', Col3, class_='grd-row-col-2-6') 37 | Col4 = NewTag('Col4', 'div', Col4, class_='grd-row-col-2-6') 38 | Col5 = NewTag('Col5', 'div', Col5, class_='grd-row-col-3-6') 39 | Col6 = NewTag('Col6', 'div', Col6, class_='grd-row-col-3-6') 40 | Col7 = NewTag('Col7', 'div', Col7, class_='grd-row-col-4-6') 41 | Col8 = NewTag('Col8', 'div', Col8, class_='grd-row-col-4-6') 42 | Col9 = NewTag('Col9', 'div', Col9, class_='grd-row-col-5-6') 43 | Col10 = NewTag('Col10', 'div', Col10, class_='grd-row-col-5-6') 44 | Col11 = NewTag('Col11', 'div', Col11, class_='grd-row-col-5-6') 45 | 46 | 47 | extended_classes = [ 48 | Button, 49 | DefaultButton, 50 | PrimaryButton, 51 | SecondaryButton, 52 | SuccessButton, 53 | InfoButton, 54 | WarningButton, 55 | DangerButton, 56 | ErrorButton, 57 | LinkButton, 58 | Container, 59 | Wrapper, 60 | Row, 61 | Col, 62 | Col1, 63 | Col2, 64 | Col3, 65 | Col4, 66 | Col5, 67 | Col6, 68 | Col7, 69 | Col8, 70 | Col9, 71 | Col10, 72 | Col11, 73 | ] 74 | -------------------------------------------------------------------------------- /wdom/themes/groundwork.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Groundwork' 9 | project_url = 'https://groundworkcss.github.io/groundwork/' 10 | project_repository = 'https://github.com/groundworkcss/groundwork' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/groundworkcss/groundwork/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '_static/css/groundwork.css', 16 | ] 17 | 18 | js_files = [ 19 | '//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js', 20 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', 21 | '_static/js/groundwork.all.js', 22 | ] 23 | 24 | Button = NewTag('Button', bases=Button) 25 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 26 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='blue', is_='primary-button') 27 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='turquoise', is_='secondary-button') 28 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success', is_='success-button') 29 | InfoButton = NewTag('InfoButton', 'button', Button, class_='info', is_='info-button') 30 | WarningButton = NewTag('WarningButton', 'button', Button, class_='warning', is_='warning-button') 31 | DangerButton = NewTag('DangerButton', 'button', Button, class_='error', is_='danger-button') 32 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='error', is_='error-button') 33 | LinkButton = NewTag('LinkButton', 'button', Button, class_='green', is_='link-button') 34 | 35 | Row = NewTag('Row', 'div', Row, class_='row') 36 | Col1 = NewTag('Col1', 'div', Col1, class_='one twelfth') 37 | Col2 = NewTag('Col2', 'div', Col2, class_='one sixth') 38 | Col3 = NewTag('Col3', 'div', Col3, class_='one fourth') 39 | Col4 = NewTag('Col4', 'div', Col4, class_='one third') 40 | Col5 = NewTag('Col5', 'div', Col5, class_='five twelfths') 41 | Col6 = NewTag('Col6', 'div', Col6, class_='one half') 42 | Col7 = NewTag('Col7', 'div', Col7, class_='seven twelfths') 43 | Col8 = NewTag('Col8', 'div', Col8, class_='two thirds') 44 | Col9 = NewTag('Col9', 'div', Col9, class_='three fourths') 45 | Col10 = NewTag('Col10', 'div', Col10, class_='five sixths') 46 | Col11 = NewTag('Col11', 'div', Col11, class_='eleven twelfths') 47 | 48 | extended_classes = [ 49 | Button, 50 | DefaultButton, 51 | PrimaryButton, 52 | SecondaryButton, 53 | SuccessButton, 54 | InfoButton, 55 | WarningButton, 56 | DangerButton, 57 | ErrorButton, 58 | LinkButton, 59 | Row, 60 | Col1, 61 | Col2, 62 | Col3, 63 | Col4, 64 | Col5, 65 | Col6, 66 | Col7, 67 | Col8, 68 | Col9, 69 | Col10, 70 | Col11, 71 | ] 72 | -------------------------------------------------------------------------------- /wdom/themes/ink.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'INK' 9 | project_url = 'http://ink.sapo.pt/' 10 | project_repository = 'https://github.com/sapo/Ink/' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/sapo/Ink/blob/develop/LICENSE' 13 | 14 | css_files = [ 15 | '//fastly.ink.sapo.pt/3.1.10/css/ink.css', 16 | ] 17 | js_files = [ 18 | '//fastly.ink.sapo.pt/3.1.10/js/ink-all.js', 19 | ] 20 | headers = [] 21 | 22 | Button = NewTag('Button', 'button', Button, class_='ink-button') 23 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 24 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='blue', is_='primary-button') 25 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, is_='secondary-button') 26 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='green', is_='success-button') 27 | InfoButton = NewTag('InfoButton', 'button', Button, class_='black', is_='info-button') 28 | WarningButton = NewTag('WarningButton', 'button', Button, class_='orange', is_='warning-button') 29 | DangerButton = NewTag('DangerButton', 'button', Button, class_='red', is_='danger-button') 30 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='red', is_='error-button') 31 | LinkButton = NewTag('LinkButton', 'button', Button, is_='link-button') 32 | 33 | Form = NewTag('Form', 'form', Form, class_='ink-form') 34 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='control-group') 35 | Input = NewTag('Input', 'input', Input) 36 | TextInput = NewTag('TextInput', 'input', TextInput) 37 | Textarea = NewTag('Textarea', 'textarea', Textarea) 38 | Select = NewTag('Select', 'ul', Ul, class_='dropdown-menu') 39 | Option = NewTag('Option', 'li', Li) 40 | 41 | Table = NewTag('Table', 'table', Table, class_='ink-table') 42 | 43 | Container = NewTag('Container', 'div', Container, class_='ink-grid') 44 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='ink-grid') 45 | Row = NewTag('Row', 'div', Row, class_='column-group') 46 | Col1 = NewTag('Col1', 'div', Col1, class_='all-10') 47 | Col2 = NewTag('Col2', 'div', Col2, class_='all-15') 48 | Col3 = NewTag('Col3', 'div', Col3, class_='all-25') 49 | Col4 = NewTag('Col4', 'div', Col4, class_='all-33') 50 | Col5 = NewTag('Col5', 'div', Col5, class_='all-40') 51 | Col6 = NewTag('Col6', 'div', Col6, class_='all-50') 52 | Col7 = NewTag('Col7', 'div', Col7, class_='all-60') 53 | Col8 = NewTag('Col8', 'div', Col8, class_='all-66') 54 | Col9 = NewTag('Col9', 'div', Col9, class_='all-75') 55 | Col10 = NewTag('Col10', 'div', Col10, class_='all-85') 56 | Col11 = NewTag('Col11', 'div', Col11, class_='all-90') 57 | Col12 = NewTag('Col12', 'div', Col12, class_='all-100') 58 | 59 | extended_classes = [ 60 | Button, 61 | DefaultButton, 62 | PrimaryButton, 63 | SecondaryButton, 64 | SuccessButton, 65 | InfoButton, 66 | WarningButton, 67 | DangerButton, 68 | ErrorButton, 69 | LinkButton, 70 | Form, 71 | FormGroup, 72 | Input, 73 | TextInput, 74 | Textarea, 75 | Select, 76 | Option, 77 | Table, 78 | Container, 79 | Wrapper, 80 | Row, 81 | Col1, 82 | Col2, 83 | Col3, 84 | Col4, 85 | Col5, 86 | Col6, 87 | Col7, 88 | Col8, 89 | Col9, 90 | Col10, 91 | Col11, 92 | Col12, 93 | ] 94 | -------------------------------------------------------------------------------- /wdom/themes/kathamo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import Button as _Button 7 | from wdom.themes import * 8 | 9 | name = 'KATHAMO' 10 | project_url = 'http://kathamo.github.io/' 11 | project_repository = 'https://github.com/kathamo/Kathamo' 12 | license = 'MIT License' 13 | license_url = 'https://github.com/kathamo/Kathamo/blob/master/LICENSE' 14 | 15 | css_files = [ 16 | '_static/css/kathamo.min.css', 17 | ] 18 | 19 | class Button(_Button): 20 | def __init__(self, *args, **kwargs): 21 | super().__init__(*args, **kwargs) 22 | self.setAttribute('data-role', 'button') 23 | 24 | 25 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 26 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, is_='primary-button') 27 | SecondaryButton = NewTag('DefaultButton', 'button', Button, is_='secondary-button') 28 | SuccessButton = NewTag('DefaultButton', 'button', Button, is_='success-button') 29 | InfoButton = NewTag('InfoButton', 'button', Button, is_='info-button') 30 | WarningButton = NewTag('WarningButton', 'button', Button, is_='warning-button') 31 | DangerButton = NewTag('DangerButton', 'button', Button, is_='danger-button') 32 | ErrorButton = NewTag('ErrorButton', 'button', Button, is_='error-button') 33 | LinkButton = NewTag('LinkButton', 'button', Button, is_='link-button') 34 | 35 | Row = NewTag('Row', 'div', Row, class_='container') 36 | Col1 = NewTag('Col1', 'div', Col1, class_='col-sm-1 col-md-1 col-lg-1') 37 | Col2 = NewTag('Col2', 'div', Col2, class_='col-sm-2 col-md-2 col-lg-2') 38 | Col3 = NewTag('Col3', 'div', Col3, class_='col-sm-3 col-md-3 col-lg-3') 39 | Col4 = NewTag('Col4', 'div', Col4, class_='col-sm-4 col-md-4 col-lg-4') 40 | Col5 = NewTag('Col5', 'div', Col5, class_='col-sm-5 col-md-5 col-lg-5') 41 | Col6 = NewTag('Col6', 'div', Col6, class_='col-sm-6 col-md-6 col-lg-6') 42 | Col7 = NewTag('Col7', 'div', Col7, class_='col-sm-7 col-md-7 col-lg-7') 43 | Col8 = NewTag('Col8', 'div', Col8, class_='col-sm-8 col-md-8 col-lg-8') 44 | Col9 = NewTag('Col9', 'div', Col9, class_='col-sm-9 col-md-9 col-lg-9') 45 | Col10 = NewTag('Col10', 'div', Col10, class_='col-sm-10 col-md-10 col-lg-10') 46 | Col11 = NewTag('Col11', 'div', Col11, class_='col-sm-11 col-md-11 col-lg-11') 47 | 48 | extended_classes = [ 49 | DefaultButton, 50 | PrimaryButton, 51 | SecondaryButton, 52 | SuccessButton, 53 | InfoButton, 54 | WarningButton, 55 | DangerButton, 56 | ErrorButton, 57 | LinkButton, 58 | Row, 59 | Col1, 60 | Col2, 61 | Col3, 62 | Col4, 63 | Col5, 64 | Col6, 65 | Col7, 66 | Col8, 67 | Col9, 68 | Col10, 69 | Col11, 70 | ] 71 | -------------------------------------------------------------------------------- /wdom/themes/kube.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Kube' 9 | project_url = 'https://imperavi.com/kube/' 10 | project_repository = 'https://github.com/imperavi/kube' 11 | license = 'MIT License' 12 | license_url = 'https://imperavi.com/kube/#kube-intro' 13 | 14 | css_files = [ 15 | '_static/css/kube.min.css', 16 | ] 17 | 18 | 19 | class TypedButton(Button): 20 | type_ = None 21 | outline = False 22 | def __init__(self, *args, **kwargs): 23 | super().__init__(*args, **kwargs) 24 | if self.type_: 25 | self.setAttribute('type', self.type_) 26 | if self.outline: 27 | self.setAttribute('outline', True) 28 | 29 | DefaultButton = NewTag('DefaultButton', 'button', TypedButton, type_='black', 30 | outline=True, is_='default-button') 31 | PrimaryButton = NewTag('PrimaryButton', 'button', TypedButton, type_='primary', is_='primary-button') 32 | SecondaryButton = NewTag('SecondaryButton', 'button', TypedButton, type_='black', 33 | outline=True, is_='secondary-button') 34 | SuccessButton = NewTag('SuccessButton', 'button', TypedButton, type_='black', is_='success-button') 35 | InfoButton = NewTag('InfoButton', 'button', TypedButton, type_='primary', 36 | outline=True, is_='info-button') 37 | WarningButton = NewTag('WarningButton', 'button', TypedButton, is_='warning-button') 38 | DangerButton = NewTag('DangerButton', 'button', TypedButton, is_='danger-button') 39 | ErrorButton = NewTag('ErrorButton', 'button', TypedButton, is_='error-button') 40 | LinkButton = NewTag('LinkButton', 'button', TypedButton, outline=True, is_='link-button') 41 | 42 | Form = NewTag('Form', 'form', Form, class_='forms') 43 | FormItem = NewTag('FormItem', 'div', FormItem, class_='form-item') 44 | Select = NewTag('Select', 'select', Select, class_='select') 45 | 46 | Row = NewTag('Row', 'row', Row) 47 | 48 | class Col(Div): 49 | tag = 'column' 50 | cols = 0 51 | def __init__(self, *args, **kwargs): 52 | super().__init__(*args, **kwargs) 53 | self.setAttribute('cols', str(self.cols)) 54 | 55 | Col1 = NewTag('Col1', 'column', Col, is_='col1') 56 | Col2 = NewTag('Col2', 'column', Col, cols=2, is_='col2') 57 | Col3 = NewTag('Col3', 'column', Col, cols=3, is_='col3') 58 | Col4 = NewTag('Col4', 'column', Col, cols=4, is_='col4') 59 | Col5 = NewTag('Col5', 'column', Col, cols=5, is_='col5') 60 | Col6 = NewTag('Col6', 'column', Col, cols=6, is_='col6') 61 | Col7 = NewTag('Col7', 'column', Col, cols=7, is_='col7') 62 | Col8 = NewTag('Col8', 'column', Col, cols=8, is_='col8') 63 | Col9 = NewTag('Col9', 'column', Col, cols=9, is_='col9') 64 | Col10 = NewTag('Col10', 'column', Col, cols=10, is_='col10') 65 | Col11 = NewTag('Col11', 'column', Col, cols=11, is_='col11') 66 | Col12 = NewTag('Col12', 'column', Col, cols=12, is_='col12') 67 | 68 | extended_classes = [ 69 | DefaultButton, 70 | PrimaryButton, 71 | SecondaryButton, 72 | SuccessButton, 73 | InfoButton, 74 | WarningButton, 75 | DangerButton, 76 | ErrorButton, 77 | LinkButton, 78 | Form, 79 | FormItem, 80 | Select, 81 | Row, 82 | Col1, 83 | Col2, 84 | Col3, 85 | Col4, 86 | Col5, 87 | Col6, 88 | Col7, 89 | Col8, 90 | Col9, 91 | Col10, 92 | Col11, 93 | Col12, 94 | ] 95 | -------------------------------------------------------------------------------- /wdom/themes/mdl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Material Design Lite (MDL)' 9 | project_url = 'http://www.getmdl.io/' 10 | project_repository = 'https://github.com/google/material-design-lite' 11 | license = 'Apache License 2.0' 12 | license_url = 'https://github.com/google/material-design-lite/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//fonts.googleapis.com/icon?family=Material+Icons', 16 | '//code.getmdl.io/1.1.3/material.indigo-pink.min.css', 17 | ] 18 | js_files = [ 19 | '//code.getmdl.io/1.1.3/material.min.js', 20 | ] 21 | headers = [] 22 | 23 | Button = NewTag('Button', bases=Button, class_='mdl-button mdl-js-button') 24 | DefaultButton = NewTag('DefaultButton', 'button', Button, 25 | class_='mdl-button--raised', is_='default-button') 26 | PrimaryButton = NewTag('PrimaryButton', 'button', DefaultButton, 27 | class_='mdl-button--primary', is_='primary-button') 28 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, 29 | class_='mdl-button--raised', is_='secondary-button') 30 | SuccessButton = NewTag('SuccessButton', 'button', DefaultButton, 31 | class_='mdl-button--accent', is_='success-button') 32 | InfoButton = NewTag('InfoButton', 'button', Button, 33 | class_='mdl-button--primary', is_='info-button') 34 | WarningButton = NewTag('WarningButton', 'button', Button, is_='warning-button') 35 | DangerButton = NewTag('DangerButton', 'button', Button, is_='danger-button') 36 | ErrorButton = NewTag('ErrorButton', 'button', Button, is_='error-button') 37 | LinkButton = NewTag('LinkButton', 'button', Button, 38 | class_='mdl-button--accent', is_='link-button') 39 | 40 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='mdl-textfield mdl-js-textfield') 41 | Input = NewTag('Input', 'input', Input, class_='mdl-textfield__input') 42 | Label = NewTag('Label', 'label', Label, class_='mdl-textfield__label') 43 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='mdl-textfield__input') 44 | Select = NewTag('Select', 'select', Select, class_='mdl-textfield__input') 45 | 46 | Table = NewTag('Table', 'table', Table, class_='mdl-data-table mdl-js-data-table') 47 | Th = NewTag('Th', 'th', Th, class_='mdl-data-table__cell--non-numeric') 48 | Td = NewTag('Td', 'td', Td, class_='mdl-data-table__cell--non-numeric') 49 | 50 | H1 = NewTag('H1', 'div', H1, class_='mdl-typography--display-4', is_='h1') 51 | H2 = NewTag('H2', 'div', H2, class_='mdl-typography--display-3', is_='h2') 52 | H3 = NewTag('H3', 'div', H3, class_='mdl-typography--display-2', is_='h3') 53 | H4 = NewTag('H4', 'div', H4, class_='mdl-typography--display-1', is_='h4') 54 | H5 = NewTag('H5', 'div', H5, class_='mdl-typography--headline', is_='h5') 55 | H6 = NewTag('H6', 'div', H6, class_='mdl-typography--title', is_='h6') 56 | 57 | Row = NewTag('Row', 'div', Row, class_='mdl-grid') 58 | Col = NewTag('Col', 'div', Col, class_='mdl-cell') 59 | Col1 = NewTag('Col1', 'div', Col1, class_='mdl-cell mdl-cell--1-col') 60 | Col2 = NewTag('Col2', 'div', Col2, class_='mdl-cell mdl-cell--2-col') 61 | Col3 = NewTag('Col3', 'div', Col3, class_='mdl-cell mdl-cell--3-col') 62 | Col4 = NewTag('Col4', 'div', Col4, class_='mdl-cell mdl-cell--4-col') 63 | Col5 = NewTag('Col5', 'div', Col5, class_='mdl-cell mdl-cell--5-col') 64 | Col6 = NewTag('Col6', 'div', Col6, class_='mdl-cell mdl-cell--6-col') 65 | Col7 = NewTag('Col7', 'div', Col7, class_='mdl-cell mdl-cell--7-col') 66 | Col8 = NewTag('Col8', 'div', Col8, class_='mdl-cell mdl-cell--8-col') 67 | Col9 = NewTag('Col9', 'div', Col9, class_='mdl-cell mdl-cell--9-col') 68 | Col10 = NewTag('Col10', 'div', Col10, class_='mdl-cell mdl-cell--10-col') 69 | Col11 = NewTag('Col11', 'div', Col11, class_='mdl-cell mdl-cell--11-col') 70 | Col12 = NewTag('Col12', 'div', Col12, class_='mdl-cell mdl-cell--12-col') 71 | 72 | extended_classes = [ 73 | Button, 74 | DefaultButton, 75 | PrimaryButton, 76 | SecondaryButton, 77 | SuccessButton, 78 | InfoButton, 79 | WarningButton, 80 | DangerButton, 81 | ErrorButton, 82 | LinkButton, 83 | FormGroup, 84 | Input, 85 | Label, 86 | Textarea, 87 | Select, 88 | Table, 89 | Th, 90 | Td, 91 | H1, 92 | H2, 93 | H3, 94 | H4, 95 | H5, 96 | H6, 97 | Row, 98 | Col, 99 | Col1, 100 | Col2, 101 | Col3, 102 | Col4, 103 | Col5, 104 | Col6, 105 | Col7, 106 | Col8, 107 | Col9, 108 | Col10, 109 | Col11, 110 | Col12, 111 | ] 112 | -------------------------------------------------------------------------------- /wdom/themes/milligram.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Milligram' 9 | project_url = 'http://milligram.github.io/' 10 | project_repository = 'https://github.com/milligram/milligram' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/milligram/milligram/blob/master/license' 13 | 14 | css_files = [ 15 | '//fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic', 16 | '//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.css', 17 | '//cdnjs.cloudflare.com/ajax/libs/milligram/1.1.0/milligram.min.css' 18 | ] 19 | 20 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='button-outline') 21 | InfoButton = NewTag('InfoButton', 'button', Button, class_='button-outline') 22 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='button-primary') 23 | LinkButton = NewTag('LinkButton', 'button', Button, class_='button-clear') 24 | Button = NewTag('Button', 'button', DefaultButton, class_='button-outline') 25 | 26 | Container = NewTag('Container', 'div', Container, class_='container') 27 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 28 | Row = NewTag('Row', 'div', Row, class_='row') 29 | Col = NewTag('Col', 'div', Col, class_='column') 30 | Col1 = NewTag('Col1', 'div', Col1, class_='column-10 column') 31 | Col2 = NewTag('Col2', 'div', Col2, class_='column-20 column') 32 | Col3 = NewTag('Col3', 'div', Col3, class_='column-25 column') 33 | Col4 = NewTag('Col4', 'div', Col4, class_='column-33 column') 34 | Col5 = NewTag('Col5', 'div', Col5, class_='column-41 column') 35 | Col6 = NewTag('Col6', 'div', Col6, class_='column-50 column') 36 | Col7 = NewTag('Col7', 'div', Col7, class_='column-60 column') 37 | Col8 = NewTag('Col8', 'div', Col8, class_='column-67 column') 38 | Col9 = NewTag('Col9', 'div', Col9, class_='column-75 column') 39 | Col10 = NewTag('Col10', 'div', Col10, class_='column-80 column') 40 | Col11 = NewTag('Col11', 'div', Col11, class_='column-90 column') 41 | Col12 = NewTag('Col12', 'div', Col12, class_='column-100 column') 42 | 43 | extended_classes = [ 44 | DefaultButton, 45 | InfoButton, 46 | PrimaryButton, 47 | LinkButton, 48 | Button, 49 | Container, 50 | Wrapper, 51 | Row, 52 | Col, 53 | Col1, 54 | Col2, 55 | Col3, 56 | Col4, 57 | Col5, 58 | Col6, 59 | Col7, 60 | Col8, 61 | Col9, 62 | Col10, 63 | Col11, 64 | Col12, 65 | ] 66 | -------------------------------------------------------------------------------- /wdom/themes/mui.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'MUI' 9 | project_url = 'https://www.muicss.com/' 10 | project_repository = 'https://github.com/muicss/mui' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/muicss/mui/blob/master/LICENSE.txt' 13 | 14 | css_files = [ 15 | '//cdn.muicss.com/mui-0.5.1/css/mui.min.css', 16 | ] 17 | js_files = [ 18 | '//cdn.muicss.com/mui-0.5.1/js/mui.min.js', 19 | ] 20 | headers = [] 21 | 22 | Button = NewTag('Button', bases=Button, class_='mui-btn') 23 | RaisedButton = NewTag('RaisedButton', 'button', Button, class_='mui-btn--raised') 24 | FlatButton = NewTag('FlatButton', 'button', Button, class_='mui-btn--flat') 25 | DefaultButton = NewTag('DefaultButton', 'button', RaisedButton, is_='default-button') 26 | PrimaryButton = NewTag('PrimaryButton', 'button', RaisedButton, class_='mui-btn--primary', is_='primary-button') 27 | SecondaryButton = NewTag('SecondaryButton', 'button', RaisedButton, class_='mui-btn--accent', is_='secondary-button') 28 | SuccessButton = NewTag('SuccessButton', 'button', RaisedButton, class_='mui-btn--accent', is_='success-button') 29 | InfoButton = NewTag('InfoButton', 'button', FlatButton, class_='mui-btn--accent', is_='info-button') 30 | WarningButton = NewTag('WarningButton', 'button', Button, class_='mui-btn--danger', is_='warning-button') 31 | DangerButton = NewTag('DangerButton', 'button', WarningButton, class_='mui-btn--raised', is_='danger-button') 32 | ErrorButton = NewTag('ErrorButton', 'button', WarningButton, class_='mui-btn--raised', is_='error-button') 33 | LinkButton = NewTag('LinkButton', 'button', FlatButton, class_='mui-btn--primary', is_='link-button') 34 | 35 | Table = NewTag('Table', 'table', Table, class_='mui-table') 36 | 37 | H1 = NewTag('H1', 'div', H1, class_='mui--text-display4', is_='h1') 38 | H2 = NewTag('H2', 'div', H2, class_='mui--text-display3', is_='h2') 39 | H3 = NewTag('H3', 'div', H3, class_='mui--text-display2', is_='h3') 40 | H4 = NewTag('H4', 'div', H4, class_='mui--text-display1', is_='h4') 41 | H5 = NewTag('H5', 'div', H5, class_='mui--text-headline', is_='h5') 42 | H6 = NewTag('H6', 'div', H6, class_='mui--text-title', is_='h6') 43 | 44 | Container = NewTag('Container', 'div', Container, class_='mui-container') 45 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='mui-container') 46 | Row = NewTag('Row', 'div', Row, class_='mui-row') 47 | 48 | Col1 = NewTag('Col1', 'div', Col1, class_='mui-col-xs-1 mui-col-sm-1 mui-col-md-1 mui-col-lg-1') 49 | Col2 = NewTag('Col2', 'div', Col2, class_='mui-col-xs-2 mui-col-sm-2 mui-col-md-2 mui-col-lg-2') 50 | Col3 = NewTag('Col3', 'div', Col3, class_='mui-col-xs-3 mui-col-sm-3 mui-col-md-3 mui-col-lg-3') 51 | Col4 = NewTag('Col4', 'div', Col4, class_='mui-col-xs-4 mui-col-sm-4 mui-col-md-4 mui-col-lg-4') 52 | Col5 = NewTag('Col5', 'div', Col5, class_='mui-col-xs-5 mui-col-sm-5 mui-col-md-5 mui-col-lg-5') 53 | Col6 = NewTag('Col6', 'div', Col6, class_='mui-col-xs-6 mui-col-sm-6 mui-col-md-6 mui-col-lg-6') 54 | Col7 = NewTag('Col7', 'div', Col7, class_='mui-col-xs-7 mui-col-sm-7 mui-col-md-7 mui-col-lg-7') 55 | Col8 = NewTag('Col8', 'div', Col8, class_='mui-col-xs-8 mui-col-sm-8 mui-col-md-8 mui-col-lg-8') 56 | Col9 = NewTag('Col9', 'div', Col9, class_='mui-col-xs-9 mui-col-sm-9 mui-col-md-9 mui-col-lg-9') 57 | Col10 = NewTag('Col10', 'div', Col10, class_='mui-col-xs-10 mui-col-sm-10 mui-col-md-10 mui-col-lg-10') 58 | Col11 = NewTag('Col11', 'div', Col11, class_='mui-col-xs-11 mui-col-sm-11 mui-col-md-11 mui-col-lg-11') 59 | 60 | extended_classes = [ 61 | Button, 62 | RaisedButton, 63 | FlatButton, 64 | DefaultButton, 65 | PrimaryButton, 66 | SecondaryButton, 67 | SuccessButton, 68 | InfoButton, 69 | WarningButton, 70 | DangerButton, 71 | ErrorButton, 72 | LinkButton, 73 | Table, 74 | H1, 75 | H2, 76 | H3, 77 | H4, 78 | H5, 79 | H6, 80 | Container, 81 | Wrapper, 82 | Row, 83 | Col1, 84 | Col2, 85 | Col3, 86 | Col4, 87 | Col5, 88 | Col6, 89 | Col7, 90 | Col8, 91 | Col9, 92 | Col10, 93 | Col11, 94 | ] 95 | -------------------------------------------------------------------------------- /wdom/themes/papier.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Papier' 9 | project_url = 'http://gugel.io/papier/' 10 | project_repository = 'https://github.com/alexanderGugel/papier' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/alexanderGugel/papier/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '//cdn.rawgit.com/alexanderGugel/papier/master/dist/papier-1.0.0.min.css', 16 | ] 17 | 18 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='bg-white') 19 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='bg-blue') 20 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='bg-grey') 21 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='bg-light-blue') 22 | InfoButton = NewTag('InfoButton', 'button', Button, class_='bg-green') 23 | WarningButton = NewTag('WarningButton', 'button', Button, class_='bg-orange') 24 | DangerButton = NewTag('DangerButton', 'button', Button, class_='bg-red') 25 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='bg-red') 26 | LinkButton = NewTag('LinkButton', 'button', Button, class_='bg-cyan') 27 | 28 | Row = NewTag('Row', 'div', Row, class_='row') 29 | Col1 = NewTag('Col1', 'div', Col1, class_='col-1') 30 | Col2 = NewTag('Col2', 'div', Col2, class_='col-2') 31 | Col3 = NewTag('Col3', 'div', Col3, class_='col-3') 32 | Col4 = NewTag('Col4', 'div', Col4, class_='col-4') 33 | Col5 = NewTag('Col5', 'div', Col5, class_='col-5') 34 | Col6 = NewTag('Col6', 'div', Col6, class_='col-6') 35 | Col7 = NewTag('Col7', 'div', Col7, class_='col-7') 36 | Col8 = NewTag('Col8', 'div', Col8, class_='col-8') 37 | Col9 = NewTag('Col9', 'div', Col9, class_='col-9') 38 | Col10 = NewTag('Col10', 'div', Col10, class_='col-10') 39 | Col11 = NewTag('Col11', 'div', Col11, class_='col-11') 40 | Col12 = NewTag('Col12', 'div', Col12, class_='col-12') 41 | 42 | extended_classes = [ 43 | DefaultButton, 44 | PrimaryButton, 45 | SecondaryButton, 46 | SuccessButton, 47 | InfoButton, 48 | WarningButton, 49 | DangerButton, 50 | ErrorButton, 51 | LinkButton, 52 | Row, 53 | Col1, 54 | Col2, 55 | Col3, 56 | Col4, 57 | Col5, 58 | Col6, 59 | Col7, 60 | Col8, 61 | Col9, 62 | Col10, 63 | Col11, 64 | Col12, 65 | ] 66 | -------------------------------------------------------------------------------- /wdom/themes/picnic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Picnic' 9 | project_url = 'http://picnicss.com/' 10 | project_repository = 'https://github.com/picnicss/picnic' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/picnicss/picnic/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '//cdn.jsdelivr.net/picnicss/5.1.0/picnic.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button) 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', Button, class_='warning', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'button', Button, class_='error', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='error', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, class_='pseudo', is_='link-button') 28 | 29 | Row = NewTag('Row', 'div', Row, class_='row') 30 | Col1 = NewTag('Col1', 'div', Col1) 31 | Col2 = NewTag('Col2', 'div', Col2) 32 | Col3 = NewTag('Col3', 'div', Col3, class_='fourth') 33 | Col4 = NewTag('Col4', 'div', Col4, class_='third') 34 | Col5 = NewTag('Col5', 'div', Col5) 35 | Col6 = NewTag('Col6', 'div', Col6, class_='half') 36 | Col7 = NewTag('Col7', 'div', Col7) 37 | Col8 = NewTag('Col8', 'div', Col8, class_='two-third') 38 | Col9 = NewTag('Col9', 'div', Col9, class_='three-fourth') 39 | Col10 = NewTag('Col10', 'div', Col10) 40 | Col11 = NewTag('Col11', 'div', Col11) 41 | Col12 = NewTag('Col12', 'div', Col12) 42 | 43 | extended_classes = [ 44 | Button, 45 | DefaultButton, 46 | PrimaryButton, 47 | SecondaryButton, 48 | SuccessButton, 49 | InfoButton, 50 | WarningButton, 51 | DangerButton, 52 | ErrorButton, 53 | LinkButton, 54 | Row, 55 | Col1, 56 | Col2, 57 | Col3, 58 | Col4, 59 | Col5, 60 | Col6, 61 | Col7, 62 | Col8, 63 | Col9, 64 | Col10, 65 | Col11, 66 | Col12, 67 | ] 68 | -------------------------------------------------------------------------------- /wdom/themes/pure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Pure' 9 | project_url = 'http://purecss.io/' 10 | project_repository = 'https://github.com/yahoo/pure/' 11 | license = 'BSD License' 12 | license_url = 'https://github.com/yahoo/pure/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '//yui.yahooapis.com/pure/0.6.0/pure-min.css', 16 | '_static/css/pure-extra.css', 17 | ] 18 | 19 | Button = NewTag('Button', bases=Button, class_='pure-button') 20 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 21 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='pure-button-primary', is_='primary-button') 22 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='pure-button-secondary', is_='secondary-button') 23 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='pure-button-success', is_='success-button') 24 | InfoButton = NewTag('InfoButton', 'button', Button, class_='pure-button-secondary', is_='info-button') 25 | WarningButton = NewTag('WarningButton', 'button', Button, class_='pure-button-warning', is_='warning-button') 26 | DangerButton = NewTag('DangerButton', 'button', Button, class_='pure-button-error', is_='danger-button') 27 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='pure-button-error', is_='error-button') 28 | LinkButton = NewTag('LinkButton', 'button', Button, class_='pure-button-link', is_='link-button') 29 | 30 | Form = NewTag('Form', 'form', Form, class_='pure-form') 31 | 32 | Table = NewTag('Table', 'table', Table, class_='pure-table') 33 | 34 | Row = NewTag('Row', 'div', Row, class_='pure-g') 35 | Col1 = NewTag('Col1', 'div', Col1, class_='pure-u-2-24') 36 | Col2 = NewTag('Col2', 'div', Col2, class_='pure-u-4-24') 37 | Col3 = NewTag('Col3', 'div', Col3, class_='pure-u-6-24') 38 | Col4 = NewTag('Col4', 'div', Col4, class_='pure-u-8-24') 39 | Col5 = NewTag('Col5', 'div', Col5, class_='pure-u-10-24') 40 | Col6 = NewTag('Col6', 'div', Col6, class_='pure-u-12-24') 41 | Col7 = NewTag('Col7', 'div', Col7, class_='pure-u-14-24') 42 | Col8 = NewTag('Col8', 'div', Col8, class_='pure-u-16-24') 43 | Col9 = NewTag('Col9', 'div', Col9, class_='pure-u-18-24') 44 | Col10 = NewTag('Col10', 'div', Col10, class_='pure-u-20-24') 45 | Col11 = NewTag('Col11', 'div', Col11, class_='pure-u-22-24') 46 | Col12 = NewTag('Col12', 'div', Col12, class_='pure-u-24-24') 47 | 48 | 49 | extended_classes = [ 50 | Button, 51 | DefaultButton, 52 | PrimaryButton, 53 | SecondaryButton, 54 | SuccessButton, 55 | InfoButton, 56 | WarningButton, 57 | DangerButton, 58 | ErrorButton, 59 | LinkButton, 60 | Form, 61 | Table, 62 | Row, 63 | Col1, 64 | Col2, 65 | Col3, 66 | Col4, 67 | Col5, 68 | Col6, 69 | Col7, 70 | Col8, 71 | Col9, 72 | Col10, 73 | Col11, 74 | Col12, 75 | ] 76 | -------------------------------------------------------------------------------- /wdom/themes/schema.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Schema' 9 | project_url = 'http://danmalarkey.github.io/schema/' 10 | project_repository = 'https://github.com/danmalarkey/schema' 11 | license = 'MIT License & CC BY 3.0 (EasyDropdown)' 12 | license_url = 'https://github.com/danmalarkey/schema#license' 13 | 14 | css_files = [ 15 | '_static/css/schema.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='btn') 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='btn-default', is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='btn-primary', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='btn-default', is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='btn-success', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, class_='btn-info', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', Button, class_='btn-warning', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'button', Button, class_='btn-danger', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='btn-danger', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, class_='btn-link', is_='link-button') 28 | 29 | FormGroup = NewTag('FormGroup', 'div', FormGroup, class_='form-group') 30 | Input = NewTag('Input', 'input', Input, class_='form-element') 31 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-element') 32 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-element') 33 | Select = NewTag('Select', 'select', Select, class_='form-element') 34 | 35 | # Lists 36 | # Ul = NewTag('Ul', 'ul', Ul, class_='list-group') 37 | # Li = NewTag('Li', 'li', Li, class_='list-group-element') 38 | 39 | Table = NewTag('Table', 'table', Table, class_='table') 40 | 41 | Container = NewTag('Container', 'div', Container, class_='container') 42 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 43 | Row = NewTag('Row', 'div', Row, class_='row-fluid') 44 | 45 | Col1 = NewTag('Col1', 'div', Col1, class_='col1') 46 | Col2 = NewTag('Col2', 'div', Col2, class_='col2') 47 | Col3 = NewTag('Col3', 'div', Col3, class_='col3') 48 | Col4 = NewTag('Col4', 'div', Col4, class_='col4') 49 | Col5 = NewTag('Col5', 'div', Col5, class_='col5') 50 | Col6 = NewTag('Col6', 'div', Col6, class_='col6') 51 | Col7 = NewTag('Col7', 'div', Col7, class_='col7') 52 | Col8 = NewTag('Col8', 'div', Col8, class_='col8') 53 | Col9 = NewTag('Col9', 'div', Col9, class_='col9') 54 | Col10 = NewTag('Col10', 'div', Col10, class_='col10') 55 | Col11 = NewTag('Col11', 'div', Col11, class_='col11') 56 | Col12 = NewTag('Col12', 'div', Col12, class_='col12') 57 | 58 | extended_classes = [ 59 | Button, 60 | DefaultButton, 61 | PrimaryButton, 62 | SecondaryButton, 63 | SuccessButton, 64 | InfoButton, 65 | WarningButton, 66 | DangerButton, 67 | ErrorButton, 68 | LinkButton, 69 | FormGroup, 70 | Input, 71 | TextInput, 72 | Textarea, 73 | Select, 74 | Table, 75 | Container, 76 | Wrapper, 77 | Row, 78 | Col1, 79 | Col2, 80 | Col3, 81 | Col4, 82 | Col5, 83 | Col6, 84 | Col7, 85 | Col8, 86 | Col9, 87 | Col10, 88 | Col11, 89 | Col12, 90 | ] 91 | -------------------------------------------------------------------------------- /wdom/themes/semantic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Semantic UI (Semantic)' 9 | project_url = 'http://semantic-ui.com/' 10 | project_repository = 'https://github.com/semantic-org/semantic-ui/' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/Semantic-Org/Semantic-UI/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.css', 16 | ] 17 | 18 | # Need jQuery 19 | js_files = [ 20 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', 21 | '//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.js', 22 | ] 23 | 24 | headers = [] 25 | 26 | # Buttons http://semantic-ui.com/elements/button.html 27 | Button = NewTag('Button', bases=Button, class_='ui button') 28 | DefaultButton = NewTag('DefaultButton', 'button', Button, is_='default-button') 29 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='primary', is_='primary-button') 30 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='blue', is_='secondary-button') 31 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='teal', is_='success-button') 32 | InfoButton = NewTag('InfoButton', 'button', Button, class_='green', is_='info-button') 33 | WarningButton = NewTag('WarningButton', 'button', Button, class_='orange', is_='warning-button') 34 | DangerButton = NewTag('DangerButton', 'button', Button, class_='red', is_='danger-button') 35 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='red', is_='error-button') 36 | LinkButton = NewTag('LinkButton', 'button', Button, class_='basic', is_='link-button') 37 | 38 | # Form http://semantic-ui.com/collections/form.html 39 | Form = NewTag('Form', 'form', Form, class_='ui form') 40 | # DropDown http://semantic-ui.com/modules/dropdown.html 41 | # document is not correct... 42 | # Select = NewTag('Select', 'select', Select, class_='ui fluid dropdown') 43 | Select = NewTag('Select', 'select', Select, class_='ui dropdown') 44 | 45 | # List http://semantic-ui.com/elements/list.html 46 | # Nested list with ul.list fails... 47 | Ul = NewTag('Ul', 'div', Div, class_='ui bulleted list', is_='ul') 48 | Li = NewTag('Li', 'div', Div, class_='item', is_='li') 49 | Ol = NewTag('Ol', 'div', Div, class_='ui ordered list', is_='ol') 50 | 51 | # Table http://semantic-ui.com/collections/table.html 52 | Table = NewTag('Table', 'table', Table, class_='ui celled table') 53 | 54 | # Divider 55 | Hr = NewTag('Hr', 'div', Div, class_='ui divider', is_='hr') 56 | 57 | # Typography http://semantic-ui.com/elements/header.html 58 | H1 = NewTag('H1', 'h1', H1, class_='ui header') 59 | H2 = NewTag('H2', 'h2', H2, class_='ui header') 60 | H3 = NewTag('H3', 'h3', H3, class_='ui header') 61 | H4 = NewTag('H4', 'h4', H4, class_='ui header') 62 | H5 = NewTag('H5', 'h5', H5, class_='ui header') 63 | H6 = NewTag('H6', 'h6', H6, class_='ui header') 64 | 65 | # Grid http://semantic-ui.com/collections/grid.html 66 | # Too complicatted... 67 | Container = NewTag('Container', 'div', Container, class_='ui grid container') 68 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='ui grid container') 69 | Row = NewTag('Row', 'div', Row, class_='row') 70 | Col = NewTag('Col', 'div', Col, class_='column') 71 | Col1 = NewTag('Col1', 'div', Col1, class_='column') 72 | Col2 = NewTag('Col2', 'div', Col2, class_='two wide column') 73 | Col3 = NewTag('Col3', 'div', Col3, class_='three wide column') 74 | Col4 = NewTag('Col4', 'div', Col4, class_='four wide column') 75 | Col5 = NewTag('Col5', 'div', Col5, class_='five wide column') 76 | Col6 = NewTag('Col6', 'div', Col6, class_='six wide column') 77 | Col7 = NewTag('Col7', 'div', Col7, class_='seven wide column') 78 | Col8 = NewTag('Col8', 'div', Col8, class_='eight wide column') 79 | Col9 = NewTag('Col9', 'div', Col9, class_='nine wide column') 80 | Col10 = NewTag('Col10', 'div', Col10, class_='ten wide column') 81 | Col11 = NewTag('Col11', 'div', Col11, class_='eleven wide column') 82 | Col12 = NewTag('Col12', 'div', Col12, class_='') 83 | 84 | extended_classes = [ 85 | Button, 86 | DefaultButton, 87 | PrimaryButton, 88 | SecondaryButton, 89 | SuccessButton, 90 | InfoButton, 91 | WarningButton, 92 | DangerButton, 93 | ErrorButton, 94 | LinkButton, 95 | Form, 96 | Select, 97 | Ul, 98 | Li, 99 | Ol, 100 | Table, 101 | Hr, 102 | H1, 103 | H2, 104 | H3, 105 | H4, 106 | H5, 107 | H6, 108 | Container, 109 | Wrapper, 110 | Row, 111 | Col, 112 | Col1, 113 | Col2, 114 | Col3, 115 | Col4, 116 | Col5, 117 | Col6, 118 | Col7, 119 | Col8, 120 | Col9, 121 | Col10, 122 | Col11, 123 | Col12, 124 | ] 125 | -------------------------------------------------------------------------------- /wdom/themes/siimple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Siimple' 9 | project_url = 'https://siimple.github.io/' 10 | project_repository = 'https://github.com/siimple/siimple/' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/siimple/siimple/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '_static/css/siimple.min.css', 16 | ] 17 | 18 | PrimaryButton = NewTag('PrimaryButton', bases=Button, class_='btn', is_='primary-button') 19 | SuccessButton = NewTag('SuccessButton', 'button', PrimaryButton, is_='success-button') 20 | InfoButton = NewTag('InfoButton', 'button', PrimaryButton, is_='info-button') 21 | WarningButton = NewTag('WarningButton', 'button', PrimaryButton, is_='warning-button') 22 | DangerButton = NewTag('DangerButton', 'button', PrimaryButton, is_='danger-button') 23 | ErrorButton = NewTag('ErrorButton', 'button', PrimaryButton, is_='error-button') 24 | Button = NewTag('Button', bases=Button, class_='btn-outline') 25 | DefaultButton = NewTag('Button', bases=Button, is_='default-button') 26 | SecondaryButton = NewTag('SecondaryButton', bases=Button, is_='secondary-button') 27 | LinkButton = NewTag('LinkButton', bases=Button, is_='link-button') 28 | 29 | Input = NewTag('Input', 'input', Input, class_='form-input') 30 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-input') 31 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-textarea') 32 | Select = NewTag('Select', 'select', Select, class_='form-select') 33 | 34 | Table = NewTag('Table', 'table', Table, class_='table') 35 | 36 | Container = NewTag('Container', 'div', Container, class_='grid grid-fluid') 37 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='grid grid-fluid') 38 | Row = NewTag('Row', 'div', Row, class_='row') 39 | 40 | Col1 = NewTag('Col1', 'div', Col1, class_='col-1') 41 | Col2 = NewTag('Col2', 'div', Col2, class_='col-2') 42 | Col3 = NewTag('Col3', 'div', Col3, class_='col-3') 43 | Col4 = NewTag('Col4', 'div', Col4, class_='col-4') 44 | Col5 = NewTag('Col5', 'div', Col5, class_='col-5') 45 | Col6 = NewTag('Col6', 'div', Col6, class_='col-6') 46 | Col7 = NewTag('Col7', 'div', Col7, class_='col-7') 47 | Col8 = NewTag('Col8', 'div', Col8, class_='col-8') 48 | Col9 = NewTag('Col9', 'div', Col9, class_='col-9') 49 | Col10 = NewTag('Col10', 'div', Col10, class_='col-10') 50 | Col11 = NewTag('Col11', 'div', Col11, class_='col-11') 51 | Col12 = NewTag('Col12', 'div', Col12, class_='col-12') 52 | 53 | extended_classes = [ 54 | PrimaryButton, 55 | SuccessButton, 56 | InfoButton, 57 | WarningButton, 58 | DangerButton, 59 | Button, 60 | DefaultButton, 61 | SecondaryButton, 62 | LinkButton, 63 | Input, 64 | TextInput, 65 | Textarea, 66 | Select, 67 | Table, 68 | Container, 69 | Wrapper, 70 | Row, 71 | Col1, 72 | Col2, 73 | Col3, 74 | Col4, 75 | Col5, 76 | Col6, 77 | Col7, 78 | Col8, 79 | Col9, 80 | Col10, 81 | Col11, 82 | Col12, 83 | ] 84 | -------------------------------------------------------------------------------- /wdom/themes/skeleton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Skeleton' 9 | project_url = 'http://getskeleton.com/' 10 | project_repository = 'https://github.com/dhg/Skeleton' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/dhg/Skeleton/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css', 16 | ] 17 | 18 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='button-primary', is_='primary-button') 19 | Container = NewTag('Container', 'div', Container, class_='container') 20 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 21 | Row = NewTag('Row', 'div', Row, class_='row') 22 | Col = NewTag('Col', 'div', Col, class_='columns') 23 | Col1 = NewTag('Col1', 'div', Col1, class_='one column') 24 | Col2 = NewTag('Col2', 'div', Col2, class_='two columns') 25 | Col3 = NewTag('Col3', 'div', Col3, class_='three columns') 26 | Col4 = NewTag('Col4', 'div', Col4, class_='four columns') 27 | Col5 = NewTag('Col5', 'div', Col5, class_='five columns') 28 | Col6 = NewTag('Col6', 'div', Col6, class_='six columns') 29 | Col7 = NewTag('Col7', 'div', Col7, class_='seven columns') 30 | Col8 = NewTag('Col8', 'div', Col8, class_='eight columns') 31 | Col9 = NewTag('Col9', 'div', Col9, class_='nine columns') 32 | Col10 = NewTag('Col10', 'div', Col10, class_='ten columns') 33 | Col11 = NewTag('Col11', 'div', Col11, class_='eleven columns') 34 | Col12 = NewTag('Col12', 'div', Col12, class_='twelve columns') 35 | 36 | extended_classes = [ 37 | PrimaryButton, 38 | Container, 39 | Wrapper, 40 | Row, 41 | Col, 42 | Col1, 43 | Col2, 44 | Col3, 45 | Col4, 46 | Col5, 47 | Col6, 48 | Col7, 49 | Col8, 50 | Col9, 51 | Col10, 52 | Col11, 53 | Col12, 54 | ] 55 | -------------------------------------------------------------------------------- /wdom/themes/skyblue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'SkyBlue' 9 | project_url = 'http://stanko.github.io/skyblue/' 10 | project_repository = 'https://github.com/Stanko/skyblue' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/Stanko/skyblue/blob/gh-pages/LICENSE.md' 13 | 14 | css_files = [ 15 | '_static/css/skyblue.min.css', 16 | ] 17 | 18 | 19 | Button = NewTag('Button', 'a', bases=A, class_='btn', is_='button') 20 | DefaultButton = NewTag('DefaultButton', 'a', Button, class_='btn-dark', is_='default-button') 21 | PrimaryButton = NewTag('PrimaryButton', 'a', Button, is_='primary-button') 22 | SecondaryButton = NewTag('SecondaryButton', 'a', Button, class_='btn-light', is_='secondary-button') 23 | SuccessButton = NewTag('SuccessButton', 'a', Button, class_='btn-success', is_='success-button') 24 | InfoButton = NewTag('InfoButton', 'a', Button, class_='btn-empty', is_='info-button') 25 | WarningButton = NewTag('WarningButton', 'a', Button, class_='btn-warning', is_='warning-button') 26 | DangerButton = NewTag('DangerButton', 'a', Button, class_='btn-error', is_='danger-button') 27 | ErrorButton = NewTag('ErrorButton', 'a', Button, class_='btn-error', is_='error-button') 28 | LinkButton = NewTag('LinkButton', 'a', Button, class_='btn-empty btn-success', is_='link-button') 29 | 30 | Input = NewTag('Input', 'input', Input, class_='form-control', type_='text') 31 | TextInput = NewTag('TextInput', 'input', TextInput, class_='form-control') 32 | Textarea = NewTag('Textarea', 'textarea', Textarea, class_='form-control') 33 | Select = NewTag('Select', 'select', Select, class_='form-control') 34 | 35 | Table = NewTag('Table', 'table', Table, class_='table') 36 | 37 | Container = NewTag('Container', 'div', Container, class_='container') 38 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 39 | Row = NewTag('Row', 'div', Row, class_='row') 40 | 41 | Col = NewTag('Col', 'div', Col, class_='col') 42 | Col1 = NewTag('Col1', 'div', Col1, class_='col xs-1 sm-1 md-1 lg-1 xl-1') 43 | Col2 = NewTag('Col2', 'div', Col2, class_='col xs-2 sm-2 md-2 lg-2 xl-2') 44 | Col3 = NewTag('Col3', 'div', Col3, class_='col xs-3 sm-3 md-3 lg-3 xl-3') 45 | Col4 = NewTag('Col4', 'div', Col4, class_='col xs-4 sm-4 md-4 lg-4 xl-4') 46 | Col5 = NewTag('Col5', 'div', Col5, class_='col xs-5 sm-5 md-5 lg-5 xl-5') 47 | Col6 = NewTag('Col6', 'div', Col6, class_='col xs-6 sm-6 md-6 lg-6 xl-6') 48 | Col7 = NewTag('Col7', 'div', Col7, class_='col xs-7 sm-7 md-7 lg-7 xl-7') 49 | Col8 = NewTag('Col8', 'div', Col8, class_='col xs-8 sm-8 md-8 lg-8 xl-8') 50 | Col9 = NewTag('Col9', 'div', Col9, class_='col xs-9 sm-9 md-9 lg-9 xl-9') 51 | Col10 = NewTag('Col10', 'div', Col10, class_='col xs-10 sm-10 md-10 lg-10 xl-10') 52 | Col11 = NewTag('Col11', 'div', Col11, class_='col xs-11 sm-11 md-11 lg-11 xl-11') 53 | Col12 = NewTag('Col12', 'div', Col12, class_='col xs-12 sm-12 md-12 lg-12 xl-12') 54 | 55 | extended_classes = [ 56 | Button, 57 | DefaultButton, 58 | PrimaryButton, 59 | SecondaryButton, 60 | SuccessButton, 61 | InfoButton, 62 | WarningButton, 63 | DangerButton, 64 | ErrorButton, 65 | LinkButton, 66 | Input, 67 | TextInput, 68 | Textarea, 69 | Select, 70 | Table, 71 | Container, 72 | Wrapper, 73 | Row, 74 | Col, 75 | Col1, 76 | Col2, 77 | Col3, 78 | Col4, 79 | Col5, 80 | Col6, 81 | Col7, 82 | Col8, 83 | Col9, 84 | Col10, 85 | Col11, 86 | Col12, 87 | ] 88 | -------------------------------------------------------------------------------- /wdom/themes/spark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import Form as _Form 7 | from wdom.themes import * 8 | 9 | name = 'Spark' 10 | project_url = 'http://codewithspark.com/' 11 | project_repository = 'https://github.com/twistedpixel/spark/' 12 | license = 'MIT License' 13 | license_url = 'https://github.com/twistedpixel/spark/blob/master/dist/LICENSE' 14 | 15 | css_files = [ 16 | '_static/css/spark.min.css', 17 | ] 18 | 19 | js_files = [ 20 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', 21 | '_static/js/spark.min.js', 22 | ] 23 | 24 | headers = [] 25 | 26 | Button = NewTag('Button', bases=Button, class_='btn flat') 27 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='black', is_='default-button') 28 | PrimaryButton = NewTag('PrimaryButton', 'button', Button, class_='blue', is_='primary-button') 29 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='green', is_='secondary-button') 30 | SuccessButton = NewTag('SuccessButton', 'button', Button, class_='lime', is_='success-button') 31 | InfoButton = NewTag('InfoButton', 'button', Button, class_='green', is_='info-button') 32 | WarningButton = NewTag('WarningButton', 'button', Button, class_='orange', is_='warning-button') 33 | DangerButton = NewTag('DangerButton', 'button', Button, class_='red', is_='danger-button') 34 | ErrorButton = NewTag('ErrorButton', 'button', Button, class_='red', is_='error-button') 35 | LinkButton = NewTag('LinkButton', 'button', Button, class_='flat', is_='link-button') 36 | 37 | class Form(_Form): 38 | class_ = 'form' 39 | def __init__(self, *args, **kwargs): 40 | super().__init__(*args, **kwargs) 41 | self.setAttribute('role', 'form') 42 | 43 | Table = NewTag('Table', 'table', Table, class_='tbl') 44 | 45 | Container = NewTag('Container', 'div', Container, class_='container') 46 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 47 | Row = NewTag('Row', 'div', Row, class_='row') 48 | Col = NewTag('Col', 'div', Col, class_='col') 49 | Col1 = NewTag('Col1', 'div', Col1, class_='col of-1') 50 | Col2 = NewTag('Col2', 'div', Col2, class_='col of-2') 51 | Col3 = NewTag('Col3', 'div', Col3, class_='col of-3') 52 | Col4 = NewTag('Col4', 'div', Col4, class_='col of-4') 53 | Col5 = NewTag('Col5', 'div', Col5, class_='col of-5') 54 | Col6 = NewTag('Col6', 'div', Col6, class_='col of-6') 55 | Col7 = NewTag('Col7', 'div', Col7, class_='col of-7') 56 | Col8 = NewTag('Col8', 'div', Col8, class_='col of-8') 57 | Col9 = NewTag('Col9', 'div', Col9, class_='col of-9') 58 | Col10 = NewTag('Col10', 'div', Col10, class_='col of-10') 59 | Col11 = NewTag('Col11', 'div', Col11, class_='col of-11') 60 | Col12 = NewTag('Col12', 'div', Col12, class_='col of-12') 61 | 62 | extended_classes = [ 63 | Button, 64 | DefaultButton, 65 | PrimaryButton, 66 | SecondaryButton, 67 | SuccessButton, 68 | InfoButton, 69 | WarningButton, 70 | DangerButton, 71 | ErrorButton, 72 | LinkButton, 73 | Table, 74 | Container, 75 | Wrapper, 76 | Row, 77 | Col, 78 | Col1, 79 | Col2, 80 | Col3, 81 | Col4, 82 | Col5, 83 | Col6, 84 | Col7, 85 | Col8, 86 | Col9, 87 | Col10, 88 | Col11, 89 | Col12, 90 | ] 91 | -------------------------------------------------------------------------------- /wdom/themes/spectre.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Spectre' 9 | project_url = 'https://picturepan2.github.io/spectre' 10 | project_repository = 'https://github.com/picturepan2/spectre' 11 | license = 'MIT License' 12 | license_url = 'https://github.com/picturepan2/spectre/blob/master/LICENSE' 13 | 14 | css_files = [ 15 | '_static/css/spectre.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='btn') 19 | DefaultButton = NewTag('Button', bases=Button) 20 | PrimaryButton = NewTag('PrimaryButton', bases=Button, class_='btn-primary') 21 | SecondaryButton = NewTag('SecondaryButton', bases=Button) 22 | SuccessButton = NewTag('SuccessButton', 'button', Button) 23 | InfoButton = NewTag('InfoButton', 'button', Button) 24 | WarningButton = NewTag('WarningButton', 'button', PrimaryButton) 25 | DangerButton = NewTag('DangerButton', 'button', PrimaryButton) 26 | ErrorButton = NewTag('ErrorButton', 'button', PrimaryButton) 27 | LinkButton = NewTag('LinkButton', bases=Button, class_='btn-link') 28 | 29 | FormGroup = NewTag('FormGroup', 'div', FormGroup) 30 | FormInner = NewTag('FormInner', 'div', FormGroup, class_='form-group') 31 | Select = NewTag('Select', 'select', Select, class_='form-select') 32 | 33 | Table = NewTag('Table', 'table', Table, class_='table') 34 | 35 | Container = NewTag('Container', 'div', Container, class_='container') 36 | Wrapper = NewTag('Wrapper', 'div', Wrapper, class_='container') 37 | Row = NewTag('Row', 'div', Row, class_='columns') 38 | Col = NewTag('Col', 'div', Col, class_='col') 39 | Col1 = NewTag('Col1', 'div', Col1, class_='col-1') 40 | Col2 = NewTag('Col2', 'div', Col2, class_='col-2') 41 | Col3 = NewTag('Col3', 'div', Col3, class_='col-3') 42 | Col4 = NewTag('Col4', 'div', Col4, class_='col-4') 43 | Col5 = NewTag('Col5', 'div', Col5, class_='col-5') 44 | Col6 = NewTag('Col6', 'div', Col6, class_='col-6') 45 | Col7 = NewTag('Col7', 'div', Col7, class_='col-7') 46 | Col8 = NewTag('Col8', 'div', Col8, class_='col-8') 47 | Col9 = NewTag('Col9', 'div', Col9, class_='col-9') 48 | Col10 = NewTag('Col10', 'div', Col10, class_='col-10') 49 | Col11 = NewTag('Col11', 'div', Col11, class_='col-11') 50 | Col12 = NewTag('Col12', 'div', Col12, class_='col-12') 51 | 52 | extended_classes = [ 53 | Button, 54 | DefaultButton, 55 | PrimaryButton, 56 | SecondaryButton, 57 | SuccessButton, 58 | InfoButton, 59 | WarningButton, 60 | DangerButton, 61 | ErrorButton, 62 | LinkButton, 63 | FormGroup, 64 | Select, 65 | Table, 66 | Container, 67 | Wrapper, 68 | Row, 69 | Col, 70 | Col1, 71 | Col2, 72 | Col3, 73 | Col4, 74 | Col5, 75 | Col6, 76 | Col7, 77 | Col8, 78 | Col9, 79 | Col10, 80 | Col11, 81 | Col12, 82 | ] 83 | -------------------------------------------------------------------------------- /wdom/themes/vital.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # flake8: noqa 4 | 5 | from wdom.tag import NewTagClass as NewTag 6 | from wdom.themes import * 7 | 8 | name = 'Vital' 9 | project_url = 'https://vitalcss.com/' 10 | project_repository = 'https://github.com/doximity/vital' 11 | license = 'Apache 2.0' 12 | license_url = 'https://github.com/doximity/vital/blob/master/LICENSE.md' 13 | 14 | css_files = [ 15 | '//cdn.rawgit.com/doximity/vital/v2.2.1/dist/css/vital.min.css', 16 | ] 17 | 18 | Button = NewTag('Button', bases=Button, class_='btn') 19 | DefaultButton = NewTag('DefaultButton', 'button', Button, class_='solid', is_='default-button') 20 | PrimaryButton = NewTag('PrimaryButton', 'button', DefaultButton, class_='blue', is_='primary-button') 21 | SecondaryButton = NewTag('SecondaryButton', 'button', Button, class_='blue', is_='secondary-button') 22 | SuccessButton = NewTag('SuccessButton', 'button', DefaultButton, class_='green', is_='success-button') 23 | InfoButton = NewTag('InfoButton', 'button', Button, class_='blue', is_='info-button') 24 | WarningButton = NewTag('WarningButton', 'button', DefaultButton, class_='orange', is_='warning-button') 25 | DangerButton = NewTag('DangerButton', 'button', DefaultButton, class_='red', is_='danger-button') 26 | ErrorButton = NewTag('ErrorButton', 'button', DefaultButton, class_='red', is_='error-button') 27 | LinkButton = NewTag('LinkButton', 'button', Button, class_='no-outline blue', is_='link-button') 28 | 29 | Ol = NewTag('Ol', 'ol', class_='list') 30 | Ul = NewTag('Ul', 'Ul', class_='list') 31 | 32 | Col = NewTag('Col', 'div', Col, class_='col') 33 | # Col1 = NewTag('Col1', 'div', Col1, class_='col-1-12') 34 | # Col2 = NewTag('Col2', 'div', Col2, class_='col-1-6') 35 | Col3 = NewTag('Col3', 'div', Col3, class_='col-1-4') 36 | Col4 = NewTag('Col4', 'div', Col4, class_='col-1-3') 37 | # Col5 = NewTag('Col5', 'div', Col5, class_='col-5-12') 38 | Col6 = NewTag('Col6', 'div', Col6, class_='col-1-2') 39 | # Col7 = NewTag('Col7', 'div', Col7, class_='col-7-12') 40 | Col8 = NewTag('Col8', 'div', Col8, class_='col-2-3') 41 | Col9 = NewTag('Col9', 'div', Col9, class_='col-3-4') 42 | # Col10 = NewTag('Col10', 'div', Col10, class_='col-5-6') 43 | # Col11 = NewTag('Col11', 'div', Col11, class_='col-11-12') 44 | # Col12 = NewTag('Col12', 'div', Col12, class_='col-1-1') 45 | -------------------------------------------------------------------------------- /wdom/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Utility functions and constants.""" 5 | 6 | import sys 7 | from os import path 8 | import logging 9 | 10 | # if freezed by cx_freeze, _static and _template dirs are copied to lib dir. 11 | if getattr(sys, 'frozen', False): 12 | root_dir = path.join(path.dirname(sys.executable), 'lib') 13 | else: 14 | root_dir = path.dirname(path.abspath(__file__)) 15 | 16 | STATIC_DIR = path.join(root_dir, '_static') 17 | TEMPLATE_DIR = path.join(root_dir, '_template') 18 | 19 | """ 20 | Include these directories when freeze your app by cx_freeze. 21 | 22 | Example: 23 | 24 | from cx_Freeze import setup 25 | form wdom.util import INCLUDE_DIRS 26 | setup(..., options = {'build_exe': {'include_files': INCLUDE_DIRS}}, ...) 27 | 28 | """ 29 | INCLUDE_DIRS = [STATIC_DIR, TEMPLATE_DIR] 30 | 31 | 32 | def install_asyncio() -> None: 33 | """Ensure that asyncio's io-loop is installed to tornado.""" 34 | pass 35 | # from tornado.ioloop import IOLoop 36 | # from tornado.platform.asyncio import AsyncIOMainLoop 37 | # if not IOLoop.initialized(): 38 | # AsyncIOMainLoop().install() 39 | 40 | 41 | def suppress_logging() -> None: 42 | """Suppress log output to stdout. 43 | 44 | This function is intended to be used in test's setup. This function removes 45 | log handler of ``wdom`` logger and set NullHandler to suppress log. 46 | """ 47 | from wdom import options 48 | options.root_logger.removeHandler(options._log_handler) 49 | options.root_logger.addHandler(logging.NullHandler()) 50 | 51 | 52 | def reset() -> None: 53 | """Reset all wdom objects. 54 | 55 | This function clear all connections, elements, and resistered custom 56 | elements. This function also makes new document/application and set them. 57 | """ 58 | from wdom.document import get_new_document, set_document 59 | from wdom.element import Element 60 | from wdom.server import _tornado 61 | from wdom.window import customElements 62 | 63 | set_document(get_new_document()) 64 | _tornado.connections.clear() 65 | _tornado.set_application(_tornado.Application()) 66 | Element._elements_with_id.clear() 67 | Element._element_buffer.clear() 68 | customElements.reset() 69 | -------------------------------------------------------------------------------- /wdom/window.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """Window and CustomElementsRegistry classes.""" 5 | 6 | from typing import Any, Dict, Type, TYPE_CHECKING 7 | 8 | from wdom import server 9 | from wdom.element import Element 10 | from wdom.event import WebEventTarget 11 | from wdom.node import Node 12 | from wdom.tag import Tag, default_classes 13 | 14 | if TYPE_CHECKING: 15 | from typing import Optional # noqa: F401 16 | 17 | 18 | class CustomElementsRegistry(dict): 19 | """Registry of registered custom elements. 20 | 21 | Keep custom elements by name (custom-tag or is-attr) and extended-tag 22 | (or None) pair. 23 | """ 24 | 25 | def _upgrage_to_tag_class(self, elm: Node) -> None: 26 | if elm.type_ and 'type' not in elm.attributes: 27 | elm.setAttribute('type', elm.type_) 28 | if elm.is_ and 'is' not in elm.attributes: 29 | elm.setAttribute('is', elm.is_) 30 | 31 | def _upgrade_by_tag(self, name: str, constructor: type) -> None: 32 | for elm in Element._element_buffer: 33 | if not elm._registered and elm.tag == name: 34 | elm.__class__ = constructor 35 | elm._registered = True 36 | if isinstance(elm, Tag): 37 | self._upgrage_to_tag_class(elm) 38 | 39 | def _upgrade_by_is(self, name: str, constructor: type, extends: str 40 | ) -> None: 41 | for elm in Element._element_buffer: 42 | if (not elm._registered and elm.tag == extends and 43 | elm.getAttribute('is') == name): 44 | elm.__class__ = constructor 45 | elm._registered = True 46 | if isinstance(elm, Tag): 47 | self._upgrage_to_tag_class(elm) 48 | 49 | def _define(self, name: str, constructor: type, 50 | options: Dict[str, str] = None) -> None: 51 | extends = None # Optional[str] 52 | if options: 53 | extends = options['extends'].lower() 54 | self[(name, extends)] = constructor 55 | if extends: 56 | self._upgrade_by_is(name, constructor, extends) 57 | else: 58 | self._upgrade_by_tag(name, constructor) 59 | 60 | def _define_orig(self, name: str, constructor: Type[Tag], 61 | options: dict = None 62 | ) -> None: 63 | self._define(name.lower(), constructor, options) 64 | 65 | def _define_class(self, constructor: Type[Tag]) -> None: 66 | is_ = getattr(constructor, 'is_', getattr(constructor, 'is', None)) 67 | if is_: 68 | name = is_.lower() 69 | options = {'extends': constructor.tag} 70 | else: 71 | name = constructor.tag.lower() 72 | options = {} 73 | self._define(name, constructor, options) 74 | 75 | def define(self, *args: Any, **kwargs: Any) -> None: 76 | """Add new custom element.""" 77 | if isinstance(args[0], str): 78 | self._define_orig(*args, **kwargs) 79 | elif isinstance(args[0], type): 80 | self._define_class(*args, **kwargs) 81 | else: 82 | raise TypeError( 83 | 'Invalid argument for define: {}, {}'.format(args, kwargs)) 84 | 85 | def _define_default(self) -> None: 86 | for cls in default_classes: 87 | self.define(cls) 88 | 89 | def reset(self) -> None: 90 | """Clear all registered custom elements.""" 91 | self.clear() 92 | self._define_default() 93 | 94 | 95 | customElements = CustomElementsRegistry() 96 | customElements._define_default() 97 | 98 | 99 | class Window(WebEventTarget): 100 | """Window base class.""" 101 | 102 | @property 103 | def document(self) -> Node: 104 | """Return document object of this window.""" 105 | return self._document 106 | 107 | @property 108 | def ownerDocument(self) -> Node: 109 | """Need for connection check.""" 110 | return self.document 111 | 112 | @property 113 | def customElements(self) -> CustomElementsRegistry: 114 | """Return customElementsRegistry object.""" 115 | return self._custom_elements 116 | 117 | @property 118 | def wdom_id(self) -> str: # noqa: D102 119 | return 'window' 120 | 121 | @property 122 | def connected(self) -> bool: # noqa: D102 123 | return server.is_connected() 124 | 125 | def __init__(self, document: Node) -> None: 126 | """Make new window object. 127 | 128 | :arg Document document: root document of the window. 129 | """ 130 | super().__init__() 131 | self._document = document 132 | self._custom_elements = customElements 133 | self.addEventListener('mount', self._on_mount) 134 | --------------------------------------------------------------------------------