diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 4a98a92..eef9624 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: [3.8, 3.9, "3.10", 3.11, 3.12, 3.13] #, pypy3] + python-version: [3.9, "3.10", 3.11, 3.12, 3.13, 3.14] #, pypy3] steps: - uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index 926b741..de7c437 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,88 @@ +# OS .DS_Store .Trashes -.vscode -*.pyc -venv -winvenv +Thumbs.db +ehthumbs.db +Desktop.ini + +# Editors / IDEs +.vscode/ +.idea/ +*.sublime-workspace +*.sublime-project + +# Python +*.py[cod] +*.pyo +*.pyd __pycache__/ +*.pyc +*.pyd +.Python +pip-selfcheck.json + +# Virtual environments +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +.venv/ +winvenv/ -build -dist -domonic.egg-info +# Packaging / distribution +build/ +dist/ +*.egg +*.egg-info/ +.domonic-egg-info/ +domonic.egg-info/ +.eggs/ +pip-wheel-metadata/ +wheels/ +*.whl -# sphinx +# Sphinx documentation docs/_build/ +build/docs/ + +# Coverage and test outputs +.coverage +.coverage.* +htmlcov/ +.pytest_cache/ +nosetests.xml +coverage.xml +*.cover + +# Type checkers / caches +.mypy_cache/ +.pytype/ +.pyre/ +.cache/ + +# C extensions / compiled artifacts +*.so +*.dylib +*.dll + +# Jupyter notebooks +.ipynb_checkpoints + +# Environment files / secrets +.env +.env.* +local.settings.json + +# Logs and runtime files +*.log +*.tmp +*.pid + +# Misc +*.pot +*.mo -.coverage \ No newline at end of file +Pipfile.lock +poetry.lock +.cache/pypoetry/ diff --git a/README.md b/README.md index c5b4ed2..4751a78 100755 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![byteface github](https://img.shields.io/badge/GitHub-byteface-181717.svg?style=flat&logo=github)](https://github.com/byteface) -#### A DOM for making HTML with python 3! (and more) +#### A DOM for making HTML with Python 3! (and more) ### Install @@ -27,7 +27,7 @@ print(html(body(h1('Hello, World!')))) #

Hello, World!

``` -or to pretty format and insert the doctype, use an f-string: +to pretty format and insert the doctype, use an f-string: ```python mydom = html(body(h1('Hello, World!'), a("somelink", _href="somepage.html"))) @@ -44,16 +44,14 @@ print(f"{mydom}") ``` -### parsing html - -Basic useage... +### Parsing html ```bash from domonic import domonic mydom = domonic.parseString(' ``` -### rendering DOM objects +### Rendering DOM objects -domonic is a pure python dom whos tree is composed of objects. i.e +domonic is a pure Python dom whos tree is composed of objects. i.e ```python div() @@ -155,7 +151,7 @@ DOM manipulation with python. ### createElement -to create your own elements use the DOM API +Create your own elements with the DOM API ```python from domonic.dom import * @@ -198,9 +194,9 @@ from domonic.dom import document print(document) ``` -### javascript +### Javascript -There is a javascript package that mimics the js API: +There is a Javascript package that mimics the js API: ```python from domonic.javascript import Math @@ -284,7 +280,7 @@ print(atag) # ``` -For writing and using regular javascript, load from a src... +For writing and using regular Javascript, load from a src... ```python script(_src="/docs/5.0/dist/js/bootstrap.bundle.min.js", _integrity="sha384-1234", _crossorigin="anonymous"), @@ -330,7 +326,7 @@ style(""" """), ``` -### decorators +### Decorators use decorators to wrap elements around function results @@ -354,7 +350,7 @@ It returns the tag object by default. You can pass True as a second param to the ### data-tags -python doesn't allow hyphens in parameter names. so use variable keyword argument syntax for custom data-tags +Python doesn't allow hyphens in parameter names. so use variable keyword argument syntax for custom data-tags ```python div("test", **{"_data-test":"test"} ) @@ -371,7 +367,7 @@ str(t) ### JSON (utils) -decorate any function that returns python objects to return json instead +Decorate any function that returns Python objects to return json instead ```python from domonic.decorators import as_json @@ -473,7 +469,7 @@ _webpage = html(head(),body( render( _webpage, 'hello.html' ) ``` -### dQuery (NEW) +### dQuery dQuery uses the º symbol (alt+0). @@ -497,7 +493,7 @@ print(b) Only recently started so check to see what's implemented. -### terminal +### Terminal There is a command line package that can call bash/unix/posix and other apps on the command line: @@ -574,31 +570,31 @@ To view the online the docs: domonic -h ``` -To see the version: +See the version: ```bash domonic -v ``` -To quickly create a domonic project for prototyping: +Quickly create a domonic project for prototyping: ```bash domonic -p myproject ``` -To evaluate some domonic pyml: +Evaluate some domonic pyml: ```bash domonic -e 'html(head(),body(div()))' ``` -To use xpath on a website from the command line: +Use xpath on a website from the command line: ```bash domonic -x https://google.com '//a' ``` -To use css selectors on a website from the command line: +Use css selectors on a website from the command line: ```bash domonic -q https://google.com 'a' @@ -618,21 +614,7 @@ Checkout [the docs](https://domonic.readthedocs.io/) for more examples i.e. gene There's also several useage examples in the repo so pull and have a look. -### Join-In - -Feel free to contribute if you find it useful. (I'd be grateful for help on all fronts) - -Email me, message me directly if you like or create a discussion on here. Or join the [discord](https://discord.gg/a9pSZv4V5f). - -If there are any methods you want that are missing or not complete yet or you think you can help make it better just update the code and send a pull request. I'll merge and releaese asap. - -In the repo there's a requirements-dev.txt which is mostly the libs used in the examples. - -requirements.txt are the libs used for packaging just the lib. - -See also the CONTRIBUTING.md - -### running examples +### Running the examples ```bash . venv/bin/activate @@ -641,7 +623,7 @@ cd examples python lifecalendar.py ``` -### run tests +### Run the tests There are tests used during dev. They are useful as code examples and to see what still needs doing. @@ -651,7 +633,7 @@ See Makefile to run all tests: make test # default tests ubuntu. so will fail on window when terminal test runs. comment out locally if that's the case ``` -or to test a single function: +Testing a single function: ```bash python -m unittest tests.test_javascript.TestCase.test_javascript_array @@ -660,7 +642,7 @@ python -m unittest tests.test_geom.TestCase.test_vec2 python3 -m unittest tests.test_cmd.TestCase.test_cmd_dir # only windows ``` -or to test a whole module +Test a whole module ```bash python -m unittest tests.test_html @@ -681,9 +663,11 @@ pip install pytest pytest tests ``` +## Contributing +Contributions are welcome! If you'd like to contribute, please follow these steps: +1. Fork the repository. +2. Create a new branch for your feature or bug fix. +3. Write your code and add tests if applicable. +4. Submit a pull request with a clear description of your changes. -### Disclaimer - -There's several more widely supported libraries doing HTML generation, DOM reading/manipulation, terminal wrappers etc. Maybe use one of those for production due to strictness and support. - -This is more of a fast prototyping library. +For more details, see the [CONTRIBUTING.md](CONTRIBUTING.md) file. diff --git a/archive/bs5_test_carousel.html b/archive/bs5_test_carousel.html deleted file mode 100644 index b23bd94..0000000 --- a/archive/bs5_test_carousel.html +++ /dev/null @@ -1,15 +0,0 @@ -Carousel Template · Bootstrap
Carousel
  • Example headline.

    Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

    Sign up today

    Another example headline.

    Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

    Learn more

    One more for good measure.

    Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.

    Browse gallery

    PreviousNext140x140

    Heading

    Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.

    View details »

    140x140

    Heading

    Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.

    View details »

    140x140

    Heading

    Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

    View details »


    First featurette heading.It’ll blow your mind.

    Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

    500x500

    Oh yeah, it’s that good.See for yourself.

    Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

    500x500

    Checkmate.And lastly, this one.

    Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

    500x500

    Back to top

    © 2017-2020 Company, Inc. ·Privacy·Terms

    \ No newline at end of file diff --git a/archive/bs5_test_checkout.html b/archive/bs5_test_checkout.html deleted file mode 100644 index d51e2d0..0000000 --- a/archive/bs5_test_checkout.html +++ /dev/null @@ -1,15 +0,0 @@ -Checkout example · Bootstrap

    Checkout form

    Below is an example form built entirely with Bootstrap’s form controls. Each required form group has a validation state that can be triggered by attempting to submit the form without completing it.

    Your cart3
    Product name
    Brief description
    $12
    Second product
    Brief description
    $8
    Third item
    Brief description
    $5
    Promo code
    EXAMPLECODE−$5Total (USD)$20

    Billing address

    Valid first name is required.
    Valid last name is required.
    @
    Your username is required.
    Please enter a valid email address for shipping updates.
    Please enter your shipping address.
    Please select a valid country.
    Please provide a valid state.
    Zip code required.


    Payment

    Full name as displayed on card
    Name on card is required
    Credit card number is required
    Expiration date required
    Security code required

    © 2020 Company Name

  • Privacy
  • Terms
  • Support
  • \ No newline at end of file diff --git a/archive/bs5_test_dashboard.html b/archive/bs5_test_dashboard.html deleted file mode 100644 index 0e4d31c..0000000 --- a/archive/bs5_test_dashboard.html +++ /dev/null @@ -1,15 +0,0 @@ -Dashboard Template · BootstrapCompany nameSaved reports

    Dashboard

    Section title

    #HeaderHeaderHeaderHeader1, 001Loremipsumdolorsit1, 002ametconsecteturadipiscingelit1, 003IntegernecodioPraesent1, 003liberoSedcursusante1, 004dapibusdiamSednisi1, 005Nullaquissemat1, 006nibhelementumimperdietDuis1, 007sagittisipsumPraesentmauris1, 008Fuscenectellussed1, 009auguesemperportaMauris1, 010massaVestibulumlaciniaarcu1, 011egetnullaClassaptent1, 012tacitisociosquadlitora1, 013torquentperconubianostra1, 014perinceptoshimenaeosCurabitur1, 015sodalesligula in libero \ No newline at end of file diff --git a/archive/domonic.jpg b/archive/domonic.jpg deleted file mode 100644 index 62d2930..0000000 Binary files a/archive/domonic.jpg and /dev/null differ diff --git a/archive/poc.py b/archive/poc.py deleted file mode 100644 index dacee1a..0000000 --- a/archive/poc.py +++ /dev/null @@ -1,68 +0,0 @@ -def render(inp, outp=""): - print(inp) - return str(inp) - - -class tag: - def __init__(self, *args, **kwargs): - self.content = "".join([each.__str__() for each in args]) - self.attributes = "".join([''' %s="%s"''' % (key.split("_")[1], value) for key, value in kwargs.items()]) - - # def __enter__(self): - # return self - - # def __exit__(self, type, value, tb): - # pass - - def __str__(self): - return f"<{self.name}{self.attributes}>{self.content}" - - -html = type("html", (tag,), {"name": "html"}) -body = type("body", (tag,), {"name": "body"}) -head = type("head", (tag,), {"name": "head"}) -script = type("script", (tag,), {"name": "script"}) -style = type("style", (tag,), {"name": "style"}) -h1 = type("h1", (tag,), {"name": "h1"}) -h2 = type("h2", (tag,), {"name": "h2"}) -h3 = type("h3", (tag,), {"name": "h3"}) -h4 = type("h4", (tag,), {"name": "h4"}) -h5 = type("h5", (tag,), {"name": "h5"}) -h6 = type("h6", (tag,), {"name": "h6"}) -p = type("p", (tag,), {"name": "p"}) -i = type("i", (tag,), {"name": "i"}) -b = type("b", (tag,), {"name": "b"}) -a = type("a", (tag,), {"name": "a"}) -ul = type("ul", (tag,), {"name": "ul"}) -ol = type("ol", (tag,), {"name": "ol"}) -li = type("li", (tag,), {"name": "li"}) -hr = type("hr", (tag,), {"name": "hr"}) -img = type("img", (tag,), {"name": "img"}) -div = type("div", (tag,), {"name": "div"}) -span = type("span", (tag,), {"name": "span"}) -strong = type("strong", (tag,), {"name": "strong"}) -blockquote = type("blockquote", (tag,), {"name": "blockquote"}) -table = type("table", (tag,), {"name": "table"}) -tr = type("tr", (tag,), {"name": "tr"}) -td = type("td", (tag,), {"name": "td"}) -title = type("title", (tag,), {"name": "title"}) -meta = type("meta", (tag,), {"name": "meta"}) - - -output = render( - html( - head( - style(), - script(), - ), - body( - div("hello world"), - a("this is a link", _href="http://www.somesite.com", _style="font-size:10px;"), - ol("".join([f"{li()}" for thing in range(5)])), - h1("test", _class="test"), - ), - ) -) - -# from html5print import HTMLBeautifier -# print(HTMLBeautifier.beautify(output, 4)) diff --git a/archive/poc1.py b/archive/poc1.py deleted file mode 100644 index f1210c7..0000000 --- a/archive/poc1.py +++ /dev/null @@ -1,278 +0,0 @@ -""" -from jizz import * - -render( html( head( script(), style() ), body(f"hello world") ) ) - -TODO - use args/kwargs for -TODO - when done. post here? .. https://stackoverflow.com/questions/6748559/generating-html-documents-in-python -TODO - throw warnings if wrong tags are used.. i.e if someone puts not li element in a ul - -TODO - consider a setting to auto render html tags.. 'asumptions=on' or something -TODO - formatting 'on' for newlines -TODO - mutlitple classnames. i.e. h1 = H1 - -""" - -# TODO - a base class to capture attributes that others can call super on. -# TODO - maybe different types of base. i.e. list containers could extend arrays -# class tag: -# def __init__(self, content='' ): -# self.content = content - -# def __str__(self): -# return str(f"{self.content}") - -# class tag: -# def __init__(self, content=''): -# self.content = content -# def __str__(self): -# return str(f"<{self.tag()}>{self.content}") -# def tag(self): -# return self.__str__().split('<')[1].split('>')[0] - - -class html: # (tag): - def __init__(self, content="", *args, **kwargs): - self.content = content # + ''.join(args) - - def __str__(self): - return str(f"{self.content}") - - -class head: - def __init__(self, content="", *args, **kwargs): - self.content = content # + ''.join([str(each.__str__()) for each in args]) - - def __str__(self): - return f"{self.content}" - - -class body: - def __init__(self, content="", *args, **kwargs): - self.content = content - self.args = args - - def __str__(self): - return f"{self.content}{''.join([each.__str__() for each in self.args])}" - - -class script: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"" - - -class style: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"" - - -class img: - def __init__(self, src="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"" - - -class div: - def __init__(self, content="", *args, **kwargs): - self.content = content - self.args = args - - def __str__(self): - # return f"
    {self.content}
    " - return f"
    {self.content}{''.join([each.__str__() for each in self.args])}
    " - - -class a: - def __init__(self, content="", attr=[], *args, **kwargs): - self.content = content - self.args = args - self.kwargs = kwargs - self.attr = attr - - def __str__(self): - # return f"{self.content}" - return f"{self.content}" - - -class footer: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"" - - -class header: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"
    {self.content}
    " - - -class ul: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"" - - -class li: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"
    {self.content}
    " - - -class p: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"

    {self.content}

    " - - -class H1: - def __init__(self, content="", *args, **kwargs): - self.content = content - - def __str__(self): - return f"

    {self.content}

    " - - -# TODO- -def render(inp, outp=""): - print(inp) - return inp - - -# render( html( head( script(), style() ), body(f"hello world") ) ) - -# render( html() ) -# render( div("hello world") ) -# render( html(body(div("hello world"))) ) - -# render( -# html( -# body( -# div("hello world"), -# div("hello world"), -# a( "this is a link", attr={"href":"http://www.fuckoff.com", "waf":"cheese"}) -# ))) - - -class tag: - def __init__(self, *args, **kwargs): - self.args = args - - def __str__(self): - return f"<{self.name}>{''.join([each.__str__() for each in self.args])}" - - -# obj = type('obj', (object,), {'propertyName' : 'propertyValue'}) -# type(obj) -span = type("span", (tag,), {"name": "span"}) -ol = type("ol", (tag,), {"name": "ol"}) - - -def get_tag(name=""): - return type(f"{name}", (tag,), {"name": f"{name}"}) - - -anything = get_tag("anything") - - -# render( -# html( -# body( -# div("hello world"), -# div("hello world"), -# a( "this is a link", href="http://www.fuckoff.com", style="font-size:10px;"), -# span("fuck"), -# ol(), -# anything() -# ))) - - -# render( -# html( -# body( -# div("hello world"), -# div("hello world"), -# a( "this is a link", href="http://www.fuckoff.com", style="font-size:10px;"), -# span("fuck"), -# ol(), -# [f'{anything()}' for thing in range(10)] -# ))) - - -# divs = [div("hello world"),div("hello world")] - -# render( -# html( -# body(divs))) - - -# TODO- -def render(inp, outp=""): - print(inp) - return inp - - -class tag: - def __init__(self, *args, **kwargs): - self.args = args - - def __str__(self): - return f"<{self.name} {[ '''%s=%s''' % (key, value) for key, value in self.kwargs.items() ]}> \ - {''.join([each.__str__() for each in self.args])}" - - -html = type("html", (tag,), {"name": "html"}) -body = type("body", (tag,), {"name": "body"}) -head = type("head", (tag,), {"name": "head"}) -script = type("script", (tag,), {"name": "script"}) -style = type("style", (tag,), {"name": "style"}) -h1 = type("h1", (tag,), {"name": "h1"}) -h2 = type("h2", (tag,), {"name": "h2"}) -h3 = type("h3", (tag,), {"name": "h3"}) -h4 = type("h4", (tag,), {"name": "h4"}) -h5 = type("h5", (tag,), {"name": "h5"}) -h6 = type("h6", (tag,), {"name": "h6"}) -p = type("p", (tag,), {"name": "p"}) -i = type("i", (tag,), {"name": "i"}) -b = type("b", (tag,), {"name": "b"}) -a = type("a", (tag,), {"name": "a"}) -ul = type("ul", (tag,), {"name": "ul"}) -ol = type("ol", (tag,), {"name": "ol"}) -li = type("li", (tag,), {"name": "li"}) -blockquote = type("blockquote", (tag,), {"name": "blockquote"}) -hr = type("hr", (tag,), {"name": "hr"}) -img = type("img", (tag,), {"name": "img"}) -div = type("div", (tag,), {"name": "div"}) -span = type("span", (tag,), {"name": "span"}) -strong = type("strong", (tag,), {"name": "strong"}) - - -render( - html( - body( - div("hello world"), - div("hello world"), - a("this is a link", href="http://www.somesite.com", style="font-size:10px;"), - span("hi"), - ol(), - [f"{anything()}" for thing in range(10)], - ) - ) -) diff --git a/archive/project.sh b/archive/project.sh deleted file mode 100644 index 5daa22f..0000000 --- a/archive/project.sh +++ /dev/null @@ -1,55 +0,0 @@ -function project(){ - - PROJECT_NAME=$1 - - NAME="byteface" - EMAIL="" - GITHUB="byteface" - LICENSE="MIT" - - echo $PROJECT_NAME - mkdir $PROJECT_NAME - cd $PROJECT_NAME - - mkdir static - mkdir static/js - mkdir static/css - mkdir static/img - mkdir static/data - - mkdir archive - - touch app.py - touch README.md - touch LICENSE - touch setup.py - touch TODO - touch index.html - touch MakeFile - touch fab.py - touch sitemap.xml - - git init - touch .gitignore - - touch db.sqlite - - touch static/js/master.js - touch static/css/styles.css - touch static/data/data.json - - python3 -m venv venv - . venv/bin/activate - - pip3 install requests - pip3 install fabric - pip3 install domonic - - pip3 freeze >> requirements.txt - - chmod -R 777 static - open . - -} - -project $1 \ No newline at end of file diff --git a/archive/test.py b/archive/test.py deleted file mode 100644 index 9864091..0000000 --- a/archive/test.py +++ /dev/null @@ -1,179 +0,0 @@ -from domonic.html import * - -# TODO - finish example using every tag - -# mycss = inlcude('static/css/mystyle.css') -# myjs = inlcude('static/js/script.js') - -repo = "http://www.github.com/byteface/domonic" -css = ".titleStyle{color:lime;}" -js = "setTimeout( function(){alert('python is fun!')}, 2000 );" - -output = html( - head( - title("domonic", _id="title"), - link( - _rel="stylesheet", - _type="text/css", - _href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.css", - ), - style(css), - script(js), - ), - body( - header( - a( - img( - _width="149", - _height="149", - _src="https://github.blog/wp-content/uploads/2008/12/forkme_right_white_ffffff.png?resize=149%2C149", - _class="attachment-full size-full", - _alt="Fork me on GitHub", - _style="float:right;", - **{"_data-recalc-dims": "1"}, - ), - _href=repo, - ) - ), - article( - h1("domonic!", _class="titleStyle"), - # h2(":)"),h3(":)"),h4(":)"),h5(":)"),h6(":)"), - div("This webpage was created with ", a("domonic", _href=repo)), - code("python3 -m pip install domonic"), - # code("pip3 install domonic"), - a(" go to the repo >>", _href=repo, _style="font-size:15px;"), - br(), - br(), - nav("Nav:", a("Go back to here again", _href=""), "|", a("repo", _href=repo)), - br(), - img(_src="http://placekitten.com/400/400", _alt="some text", _title="some text"), - br(), - ol("".join([f'{li("some item")}' for thing in range(5)])), - table( - tr(th("A"), th("B"), th("C")), - tr(td("test"), td("test"), td("test")), - tr(td("test"), td("test"), td("test")), - _style="width:100%", - ), - span("spaf", _style="color:fuchsia"), - ), - section( - figure( - img(_src="http://placekitten.com/200/200", _alt="some text", _title="some text"), - br(), - ), - figcaption("a cat"), - br(), - dl(dt("coffee"), dd("hot drink"), dt("milk"), dd("cold drink")), - form( - label("this is a label:", _for="some_input"), - br(), - input(_id="some_input", _name="some_input", _type="text", _placeholder="cool"), - br(), - input(" yer or no?", _type="radio"), - br(), - input(_value="send", _type="button"), - comment("This webpage was created with 'domonic'"), - ), - ), - iframe("test", _data_test="test", _src="https://www.google.com"), - noscript("Your browser does not support javascript"), - footer( - address("Where: Earth"), - select(option("test1", _value="test1"), option("test2", _value="test2"), option("test3", _value="test3")), - button("cool button"), - sup("sup!"), - sub("sub!"), - textarea("test"), - details(summary(small("domonic 2020."))), - ), - p(var("a"), "(", var("b"), "+", var("c"), ")=", var("ab"), "+", var("ac")), - tbody("test"), - thead("test"), - tfoot("test"), - aside("test"), - hgroup("test"), - pre("test"), - em("test"), - s("test"), - cite("test"), - q("test"), - dfn("test"), - abbr("test"), - var("test"), - samp("test"), - kbd("test"), - i("test"), - b("test"), - u("test"), - mark("test"), - ruby("test"), - rt("test"), - rp("test"), - bdi("test"), - bdo("test"), - ins("test"), - video("test"), - audio("test"), - canvas("test"), - caption("test"), - colgroup("test"), - fieldset("test"), - legend("test"), - datalist("test"), - optgroup("test"), - option("test"), - output("test"), # shite ----- - progress("test"), - meter("test"), - menu("test"), - font("test", **{"_data-test": "test"}), - # map("test"), - # del("test"), - # object("test"), - # time("test"), - ), - _lang="", -) - - -# def dom_console_log_test(): -# mydom = dom.document(output) -# mydom.console.log("test") - - -# print( "output.baseURI:", output.baseURI ) -# print( "output.body:", output.body ) -# print( "output.forms:", output.forms ) -# print( "output.images:", output.images ) -# print( "output.scripts:", output.scripts ) -# print( "output.title:", output.title ) -print("output._get_tags:", output._get_tags("li")) -print("output._get_tags:", output._get_tags("input")) -print("output._get_tags:", output._get_tags("div")) -print("output._get_tags:", output._get_tags("style")) - - -# TODO - add some methods to do cool stuff - -# print(output[0]) - -# for each in output: -# print(each) - -# print(output.content) -# print(output.attributes) - -# print(output.args) -# print(output.kwargs) - -# print(output.args[1].args[1].args[0]) - -# print(output.content[1].content[1].content[0]) -# print(output.content[1].content[2].attributes[0]) - -print(render(output)) - -# TODO - prettify by using newlines in returned content to save installing this? -# from html5print import HTMLBeautifier -# render(HTMLBeautifier.beautify(render(output), 4), 'index.html') diff --git a/domonic/CDN.py b/domonic/CDN.py index 9db0e83..5b5883c 100644 --- a/domonic/CDN.py +++ b/domonic/CDN.py @@ -1,58 +1,53 @@ """ domonic.CDN ==================================== - For quick reference when prototyping you can use the CDN package. - (Don't rely on a CDN package for production code. wget a local copy.) - - TODO - integrity/cross origin/module? + For quick reference when prototyping """ - class CDN_JS: """ - js libs + JavaScript libraries """ - JQUERY_3_5_1: str = "https://code.jquery.com/jquery-3.5.1.min.js" #: - JQUERY: str = "https://code.jquery.com/jquery-3.6.0.min.js" #: latest - JQUERY_UI: str = "https://code.jquery.com/ui/1.12.0/jquery-ui.min.js" #: - UNDERSCORE: str = "https://cdn.jsdelivr.net/npm/underscore@1.11.0/underscore-min.js" #: - BOOTSTRAP_4: str = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" #: - POPPER_1_16_1: str = "https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" #: - BOOTSTRAP_5_ALPHA: str = "https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" #: - BOOTSTRAP_5 = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" #: latest - D3_6_1_0: str = "https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.0/d3.min.js" #: - D3: str = "https://cdnjs.cloudflare.com/ajax/libs/d3/7.4.3/d3.min.js" #: latest - MODERNIZER_2_8_3: str = "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js" #: - MOMENT_2_27_0: str = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js" #: - PIXI_5_3_3: str = "https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.3.3/pixi.min.js" #: - SOCKET_1_4_5: str = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js" #: - X3DOM: str = "https://www.x3dom.org/download/x3dom.js" #: - AFRAME_1_2: str = "https://aframe.io/releases/1.2.0/aframe.min.js" #: - BRYTHON_3_9_5: str = "https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.5/brython.min.js" #: - MATHML: str = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=MML_HTMLorMML" #: - HTMX: str = "https://unpkg.com/htmx.org@1.7.0" #: latest - + JQUERY: str = "https://code.jquery.com/jquery-3.6.4.min.js" + JQUERY_UI: str = "https://code.jquery.com/ui/1.13.2/jquery-ui.min.js" + UNDERSCORE: str = "https://cdn.jsdelivr.net/npm/underscore@1.13.6/underscore-min.js" + BOOTSTRAP: str = "https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/js/bootstrap.min.js" + POPPER: str = "https://cdn.jsdelivr.net/npm/popper.js@2.11.7/dist/umd/popper.min.js" + D3: str = "https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.4/d3.min.js" + MODERNIZER: str = "https://cdnjs.cloudflare.com/ajax/libs/modernizr/3.11.7/modernizr.min.js" + MOMENT: str = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js" + PIXI: str = "https://cdnjs.cloudflare.com/ajax/libs/pixi.js/7.1.0/pixi.min.js" + SOCKET: str = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.6.1/socket.io.min.js" + X3DOM: str = "https://www.x3dom.org/download/x3dom.js" + AFRAME: str = "https://aframe.io/releases/1.3.0/aframe.min.js" + BRYTHON: str = "https://cdnjs.cloudflare.com/ajax/libs/brython/3.11.1/brython.min.js" + MATHML: str = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.min.js" + HTMX: str = "https://unpkg.com/htmx.org@1.9.0" + LODASH: str = "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" + AXIOS: str = "https://cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js" + DAY_JS: str = "https://cdn.jsdelivr.net/npm/dayjs@1.10.4/dayjs.min.js" + CHART_JS: str = "https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" + ANIME_JS: str = "https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" + VALIDATOR_JS: str = "https://cdn.jsdelivr.net/npm/validator@13.6.0/validator.min.js" class CDN_CSS: """ - Preferably use version numbers if available. - use LATEST if it always gets the latest + CSS Libraries """ - BOOTSTRAP_5_ALPHA: str = "https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" #: - BOOTSTRAP_4: str = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" #: - MARX: str = "https://unpkg.com/marx-css/css/marx.min.css" #: - MVP: str = "https://unpkg.com/mvp.css" #: - WATER_LATEST: str = "https://cdn.jsdelivr.net/gh/kognise/water.css@latest/water.min.css" #: - BALLOON: str = "https://unpkg.com/balloon-css/balloon.min.css" #: - THREE_DOTS_0_2_0: str = "https://cdnjs.cloudflare.com/ajax/libs/three-dots/0.2.0/three-dots.min.css" #: - MILLIGRAM_1_3_0: str = "https://cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.css" #: - X3DOM: str = "https://www.x3dom.org/download/x3dom.css" #: - FONTAWESOME_5_7_1: str = "https://use.fontawesome.com/releases/v5.7.1/css/all.css" #: - MDI_5_4_55: str = "https://cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css" #: - TAILWIND_2_2_15: str = "https://unpkg.com/tailwindcss@^2.2.15/dist/tailwind.min.css" #: - SIMPLE: str = "https://cdn.simplecss.org/simple.min.css" #: + BOOTSTRAP: str = "https://stackpath.bootstrapcdn.com/bootstrap/5.3.0/css/bootstrap.min.css" + MARX: str = "https://unpkg.com/marx-css/css/marx.min.css" + MVP: str = "https://unpkg.com/mvp.css" + WATER: str = "https://cdn.jsdelivr.net/gh/kognise/water.css@latest/water.min.css" + BALLOON: str = "https://unpkg.com/balloon-css/balloon.min.css" + THREE_DOTS: str = "https://cdnjs.cloudflare.com/ajax/libs/three-dots/0.2.0/three-dots.min.css" + MILLIGRAM: str = "https://cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.css" + X3DOM: str = "https://www.x3dom.org/download/x3dom.css" + FONTAWESOME: str = "https://use.fontawesome.com/releases/v5.7.1/css/all.css" + MDI: str = "https://cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css" + TAILWIND: str = "https://unpkg.com/tailwindcss@^2.2.15/dist/tailwind.min.css" + SIMPLE: str = "https://cdn.simplecss.org/simple.min.css" class CDN_IMG: diff --git a/domonic/constants/__init__.py b/domonic/constants/__init__.py index 5407ddd..a9d162f 100644 --- a/domonic/constants/__init__.py +++ b/domonic/constants/__init__.py @@ -1,11 +1,13 @@ -""" - domonic.constants - ==================================== +from typing import Dict +""" +domonic.constants +==================================== +This module defines various constants used in the domonic package. """ -#: namespaces -namespaces: dict = { +# Namespaces +namespaces: Dict[str, str] = { "xml": "http://www.w3.org/XML/1998/namespace", "svg": "http://www.w3.org/2000/svg", "xlink": "http://www.w3.org/1999/xlink", @@ -19,17 +21,9 @@ "html": "http://www.w3.org/1999/xhtml", } - -#: document types -doctypes: dict = { +# Document Types +doctypes: Dict[str, str] = { "HTML5": "", - # XHTML 1.1 - # XHTML 1.1 Strict - # XHTML 1.1 Transitional - # XHTML 1.1 Frameset - # XHTML 1.0 Strict - # XHTML 1.0 Transitional - # XHTML_1_0_Frameset = '' "HTML4_01_Strict": '', "HTML4_01_Transitional": '', "HTML4_01_Frameset": '', @@ -37,126 +31,115 @@ "HTML2": '', } +# HTTP Response Status Codes +from enum import Enum -#: html response status codes -http_response_status_codes: dict = { - 200: "200 OK", - 201: "201 Created", - 202: "202 Accepted", - 203: "203 Non-Authoritative Information", - 204: "204 No Content", - 205: "205 Reset Content", - 206: "206 Partial Content", - 207: "207 Multi-Status", - 208: "208 Already Reported", - 226: "226 IM Used", - 300: "300 Multiple Choices", - 301: "301 Moved Permanently", - 302: "302 Found", - 303: "303 See Other", - 304: "304 Not Modified", - 305: "305 Use Proxy", - 306: "306 Switch Proxy", - 307: "307 Temporary Redirect", - 308: "308 Permanent Redirect", - 400: "400 Bad Request", - 401: "401 Unauthorized", - 402: "402 Payment Required", - 403: "403 Forbidden", - 404: "404 Not Found", - 405: "405 Method Not Allowed", - 406: "406 Not Acceptable", - 407: "407 Proxy Authentication Required", - 408: "408 Request Timeout", - 409: "409 Conflict", - 410: "410 Gone", - 411: "411 Length Required", - 412: "412 Precondition Failed", - 413: "413 Payload Too Large", - 414: "414 URI Too Long", - 415: "415 Unsupported Media Type", - 416: "416 Range Not Satisfiable", - 417: "417 Expectation Failed", - 418: "418 I'm a teapot", - 421: "421 Misdirected Request", - 422: "422 Unprocessable Entity", - 423: "423 Locked", - 424: "424 Failed Dependency", - 426: "426 Upgrade Required", - 428: "428 Precondition Required", - 429: "429 Too Many Requests", - 431: "431 Request Header Fields Too Large", - 451: "451 Unavailable For Legal Reasons", - 499: "499 Client Closed Request", - 500: "500 Internal Server Error", - 501: "501 Not Implemented", - 502: "502 Bad Gateway", - 503: "503 Service Unavailable", - 504: "504 Gateway Timeout", - 505: "505 HTTP Version Not Supported", - 506: "506 Variant Also Negotiates", - 507: "507 Insufficient Storage", - 508: "508 Loop Detected", - 510: "510 Not Extended", - 511: "511 Network Authentication Required", -} - +class HTTPStatus(Enum): + OK = 200 + CREATED = 201 + ACCEPTED = 202 + NON_AUTHORITATIVE_INFORMATION = 203 + NO_CONTENT = 204 + RESET_CONTENT = 205 + PARTIAL_CONTENT = 206 + MULTI_STATUS = 207 + ALREADY_REPORTED = 208 + IM_USED = 226 + MULTIPLE_CHOICES = 300 + MOVED_PERMANENTLY = 301 + FOUND = 302 + SEE_OTHER = 303 + NOT_MODIFIED = 304 + USE_PROXY = 305 + SWITCH_PROXY = 306 + TEMPORARY_REDIRECT = 307 + PERMANENT_REDIRECT = 308 + BAD_REQUEST = 400 + UNAUTHORIZED = 401 + PAYMENT_REQUIRED = 402 + FORBIDDEN = 403 + NOT_FOUND = 404 + METHOD_NOT_ALLOWED = 405 + NOT_ACCEPTABLE = 406 + PROXY_AUTHENTICATION_REQUIRED = 407 + REQUEST_TIMEOUT = 408 + CONFLICT = 409 + GONE = 410 + LENGTH_REQUIRED = 411 + PRECONDITION_FAILED = 412 + PAYLOAD_TOO_LARGE = 413 + URI_TOO_LONG = 414 + UNSUPPORTED_MEDIA_TYPE = 415 + RANGE_NOT_SATISFIABLE = 416 + EXPECTATION_FAILED = 417 + IM_A_TEAPOT = 418 + MISDIRECTED_REQUEST = 421 + UNPROCESSABLE_ENTITY = 422 + LOCKED = 423 + FAILED_DEPENDENCY = 424 + UPGRADE_REQUIRED = 426 + PRECONDITION_REQUIRED = 428 + TOO_MANY_REQUESTS = 429 + REQUEST_HEADER_FIELDS_TOO_LARGE = 431 + UNAVAILABLE_FOR_LEGAL_REASONS = 451 + CLIENT_CLOSED_REQUEST = 499 + INTERNAL_SERVER_ERROR = 500 + NOT_IMPLEMENTED = 501 + BAD_GATEWAY = 502 + SERVICE_UNAVAILABLE = 503 + GATEWAY_TIMEOUT = 504 + HTTP_VERSION_NOT_SUPPORTED = 505 + VARIANT_ALSO_NEGOTIATES = 506 + INSUFFICIENT_STORAGE = 507 + LOOP_DETECTED = 508 + NOT_EXTENDED = 510 + NETWORK_AUTHENTICATION_REQUIRED = 511 -# file_extensions = { -# "html": "text/html", -# "htm": "text/html", -# "xhtml": "application/xhtml+xml", -# "xml": "application/xml", -# "svg": "image/svg+xml", -# "css": "text/css", -# "js": "application/javascript", -# "json": "application/json", -# "txt": "text/plain", -# "pdf": "application/pdf", -# "png": "image/png", -# "jpg": "image/jpeg", -# "jpeg": "image/jpeg", -# "gif": "image/gif", -# "ico": "image/x-icon", -# "tiff": "image/tiff", -# "tif": "image/tiff", -# "bmp": "image/bmp", -# "mp3": "audio/mpeg", -# "mp4": "video/mp4", -# "mpeg": "video/mpeg", -# "mpg": "video/mpeg", -# "mov": "video/quicktime", -# "qt": "video/quicktime", -# "avi": "video/x-msvideo", -# "wmv": "video/x-ms-wmv", -# "flv": "video/x-flv", -# "swf": "application/x-shockwave-flash", -# "zip": "application/zip", -# "gz": "application/x-gzip", -# "bz2": "application/x-bzip2", -# "rar": "application/x-rar-compressed", -# "tar": "application/x-tar", -# "7z": "application/x-7z-compressed", -# "exe": "application/x-msdownload", -# "msi": "application/x-msdownload", -# "cab": "application/vnd.ms-cab-compressed", -# "doc": "application/msword", -# "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", -# "xls": "application/vnd.ms-excel", -# "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", -# "ppt": "application/vnd.ms-powerpoint", -# "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", -# } +http_response_status_codes = {status.value: status.name.replace('_', ' ').title() for status in HTTPStatus} -# """ -# tag_states = { -# 'a' : { -# 'hover' : 'a:hover', -# 'visited' : 'a:visited', -# 'link' : 'a:link', -# 'active' : 'a:active', -# 'focus' : 'a:focus', -# # 'not' : 'a:not', -# } -# } -# """ +# Common MIME Types +file_extensions: Dict[str, str] = { + "html": "text/html", + "htm": "text/html", + "xhtml": "application/xhtml+xml", + "xml": "application/xml", + "svg": "image/svg+xml", + "css": "text/css", + "js": "application/javascript", + "json": "application/json", + "txt": "text/plain", + "pdf": "application/pdf", + "png": "image/png", + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "gif": "image/gif", + "ico": "image/x-icon", + "tiff": "image/tiff", + "tif": "image/tiff", + "bmp": "image/bmp", + "mp3": "audio/mpeg", + "mp4": "video/mp4", + "mpeg": "video/mpeg", + "mpg": "video/mpeg", + "mov": "video/quicktime", + "qt": "video/quicktime", + "avi": "video/x-msvideo", + "wmv": "video/x-ms-wmv", + "flv": "video/x-flv", + "swf": "application/x-shockwave-flash", + "zip": "application/zip", + "gz": "application/x-gzip", + "bz2": "application/x-bzip2", + "rar": "application/x-rar-compressed", + "tar": "application/x-tar", + "7z": "application/x-7z-compressed", + "exe": "application/x-msdownload", + "msi": "application/x-msdownload", + "cab": "application/vnd.ms-cab-compressed", + "doc": "application/msword", + "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "xls": "application/vnd.ms-excel", + "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "ppt": "application/vnd.ms-powerpoint", + "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation", +} diff --git a/domonic/constants/keyboard.py b/domonic/constants/keyboard.py index 0e34a4e..3afd3ef 100644 --- a/domonic/constants/keyboard.py +++ b/domonic/constants/keyboard.py @@ -1,124 +1,161 @@ -""" - domonic.constants.keyboard - =================================== +class KeyCode: + """Class representing keyboard key codes.""" -""" + # Alphabet keys + A: str = "65" + B: str = "66" + C: str = "67" + D: str = "68" + E: str = "69" + F: str = "70" + G: str = "71" + H: str = "72" + I: str = "73" + J: str = "74" + K: str = "75" + L: str = "76" + M: str = "77" + N: str = "78" + O: str = "79" + P: str = "80" + Q: str = "81" + R: str = "82" + S: str = "83" + T: str = "84" + U: str = "85" + V: str = "86" + W: str = "87" + X: str = "88" + Y: str = "89" + Z: str = "90" + # Numeric keys + NUMBER_0: str = "48" + NUMBER_1: str = "49" + NUMBER_2: str = "50" + NUMBER_3: str = "51" + NUMBER_4: str = "52" + NUMBER_5: str = "53" + NUMBER_6: str = "54" + NUMBER_7: str = "55" + NUMBER_8: str = "56" + NUMBER_9: str = "57" -class KeyCode: + # Numpad keys + NUMPAD: str = "21" + NUMPAD_0: str = "96" + NUMPAD_1: str = "97" + NUMPAD_2: str = "98" + NUMPAD_3: str = "99" + NUMPAD_4: str = "100" + NUMPAD_5: str = "101" + NUMPAD_6: str = "102" + NUMPAD_7: str = "103" + NUMPAD_8: str = "104" + NUMPAD_9: str = "105" + NUMPAD_ADD: str = "107" + NUMPAD_DECIMAL: str = "110" + NUMPAD_DIVIDE: str = "111" + NUMPAD_ENTER: str = "108" + NUMPAD_MULTIPLY: str = "106" + NUMPAD_SUBTRACT: str = "109" - A: str = "65" #: - ALTERNATE: str = "18" #: - B: str = "66" #: - BACKQUOTE: str = "192" #: - BACKSLASH: str = "220" #: - BACKSPACE: str = "8" #: - C: str = "67" #: - CAPS_LOCK: str = "20" #: - COMMA: str = "188" #: - COMMAND: str = "15" #: - CONTROL: str = "17" #: - D: str = "68" #: - DELETE: str = "46" #: - DOWN: str = "40" #: - E: str = "69" #: - END: str = "35" #: + # Special characters + EXCLAMATION: str = "49" # Shift + 1 + AT: str = "50" # Shift + 2 + HASH: str = "51" # Shift + 3 + DOLLAR: str = "52" # Shift + 4 + PERCENT: str = "53" # Shift + 5 + CARET: str = "54" # Shift + 6 + AMPERSAND: str = "55" # Shift + 7 + STAR: str = "56" # Shift + 8 + LEFT_PARENTHESIS: str = "57" # Shift + 9 + RIGHT_PARENTHESIS: str = "48" # Shift + 0 + UNDERSCORE: str = "189" # Shift + - + PLUS: str = "187" # Shift + = + LEFT_CURLY_BRACKET: str = "219" # Shift + [ + RIGHT_CURLY_BRACKET: str = "221" # Shift + ] + PIPE: str = "220" # Shift + \ + COLON: str = "186" # Shift + ; + DOUBLE_QUOTE: str = "222" # Shift + ' + LESS_THAN: str = "188" # Shift + , + GREATER_THAN: str = "190" # Shift + . + QUESTION_MARK: str = "191" # Shift + / - ENTER: str = "13" #: - RETURN: str = "13" #: + # Function keys + F1: str = "112" + F2: str = "113" + F3: str = "114" + F4: str = "115" + F5: str = "116" + F6: str = "117" + F7: str = "118" + F8: str = "119" + F9: str = "120" + F10: str = "121" + F11: str = "122" + F12: str = "123" + F13: str = "124" + F14: str = "125" + F15: str = "126" - EQUAL: str = "187" #: - ESCAPE: str = "27" #: - F: str = "70" #: - F1: str = "112" #: - F10: str = "121" #: - F11: str = "122" #: - F12: str = "123" #: - F13: str = "124" #: - F14: str = "125" #: - F15: str = "126" #: - F2: str = "113" #: - F3: str = "114" #: - F4: str = "115" #: - F5: str = "116" #: - F6: str = "117" #: - F7: str = "118" #: - F8: str = "119" #: - F9: str = "120" #: - G: str = "71" #: - H: str = "72" #: - HOME: str = "36" #: - I: str = "73" #: - INSERT: str = "45" #: - J: str = "74" #: - K: str = "75" #: - L: str = "76" #: - LEFT: str = "37" #: - LEFTBRACKET: str = "219" #: - M: str = "77" #: - MINUS: str = "189" #: - N: str = "78" #: - NUMBER_0: str = "48" #: - NUMBER_1: str = "49" #: - NUMBER_2: str = "50" #: - NUMBER_3: str = "51" #: - NUMBER_4: str = "52" #: - NUMBER_5: str = "53" #: - NUMBER_6: str = "54" #: - NUMBER_7: str = "55" #: - NUMBER_8: str = "56" #: - NUMBER_9: str = "57" #: - NUMPAD: str = "21" #: - NUMPAD_0: str = "96" #: - NUMPAD_1: str = "97" #: - NUMPAD_2: str = "98" #: - NUMPAD_3: str = "99" #: - NUMPAD_4: str = "100" #: - NUMPAD_5: str = "101" #: - NUMPAD_6: str = "102" #: - NUMPAD_7: str = "103" #: - NUMPAD_8: str = "104" #: - NUMPAD_9: str = "105" #: - NUMPAD_ADD: str = "107" #: - NUMPAD_DECIMAL: str = "110" #: - NUMPAD_DIVIDE: str = "111" #: - NUMPAD_ENTER: str = "108" #: - NUMPAD_MULTIPLY: str = "106" #: - NUMPAD_SUBTRACT: str = "109" #: - O: str = "79" #: - P: str = "80" #: - PAGE_DOWN: str = "34" #: - PAGE_UP: str = "33" #: - PERIOD: str = "190" #: - Q: str = "81" #: - QUOTE: str = "222" #: - R: str = "82" #: - RIGHT: str = "39" #: - RIGHTBRACKET: str = "221" #: - S: str = "83" #: - SEMICOLON: str = "186" #: + # Control keys + BACKSPACE: str = "8" + CAPS_LOCK: str = "20" + COMMA: str = "188" + COMMAND: str = "15" + CONTROL: str = "17" + DELETE: str = "46" + DOWN: str = "40" + END: str = "35" + ENTER: str = "13" + RETURN: str = "13" + EQUAL: str = "187" + ESCAPE: str = "27" + HOME: str = "36" + INSERT: str = "45" + LEFT: str = "37" + LEFTBRACKET: str = "219" + MINUS: str = "189" + PAGE_DOWN: str = "34" + PAGE_UP: str = "33" + PERIOD: str = "190" + QUOTE: str = "222" + RIGHT: str = "39" + RIGHTBRACKET: str = "221" + SEMICOLON: str = "186" SHIFT: str = "16" #: ?? left or right or both? - SLASH: str = "191" #: - SPACE: str = "32" #: - T: str = "84" #: - TAB: str = "9" #: - U: str = "85" #: - UP: str = "38" #: - V: str = "86" #: - W: str = "87" #: - X: str = "88" #: - Y: str = "89" #: - Z: str = "9" #: + SLASH: str = "191" + SPACE: str = "32" + TAB: str = "9" + UP: str = "38" + + # Modifier keys + LEFT_SHIFT: str = "16L" + RIGHT_SHIFT: str = "16R" + LEFT_CONTROL: str = "17L" + RIGHT_CONTROL: str = "17R" + LEFT_ALT: str = "18L" + RIGHT_ALT: str = "18R" + LEFT_COMMAND: str = "91L" # Left Apple/Command key + RIGHT_COMMAND: str = "93R" # Right Apple/Command key + FN: str = "255" # Fn key - # TODO - do the modifiers + # Media Control Keys + VOLUME_UP: str = "175" + VOLUME_DOWN: str = "174" + MUTE: str = "173" + PLAY_PAUSE: str = "179" + NEXT_TRACK: str = "176" + PREVIOUS_TRACK: str = "177" - # find attribute by value - # def get_letter(self, attr): - # for key, value in self.__dict__.iteritems(): - # if value: str == attr: - # return key - # return None + # Special Keys + WINDOWS: str = "91" # Windows key + MENU: str = "93" # Menu key + PRINT_SCREEN: str = "44" + SCROLL_LOCK: str = "145" + PAUSE_BREAK: str = "19" def __init__(self) -> None: - """constructor for the KeyCode class""" + """Constructor for the KeyCode class.""" pass diff --git a/requirements.txt b/requirements.txt index b1b6e8a..d7db877 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -elementpath~=4.6.0 -python-dateutil==2.9.0.post0 -requests~=2.32.3 -urllib3~=2.2.3 -html5lib~=1.1 -cssselect~=1.2.0 \ No newline at end of file +elementpath>=4.8,<5 +python-dateutil>=2.9,<3 +requests>=2.32,<3 +urllib3>=2.4,<3 +html5lib>=1.1,<2 +cssselect>=1.3,<2 diff --git a/setup.py b/setup.py index e9a3ee6..b59a5fa 100644 --- a/setup.py +++ b/setup.py @@ -68,13 +68,12 @@ def get_requirements(filename: str = "requirements.txt"): "Programming Language :: Python :: 3", "Programming Language :: JavaScript", "Programming Language :: Python", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", diff --git a/tests/test_CDN.py b/tests/test_CDN.py index 4a2e207..8f53779 100644 --- a/tests/test_CDN.py +++ b/tests/test_CDN.py @@ -12,12 +12,10 @@ class TestCase(unittest.TestCase): def test_domonic_CDN(self): - myjs = script(_src=CDN_JS.JQUERY_3_5_1) - assert str(myjs) == '' + myjs = script(_src=CDN_JS.JQUERY) + assert str(myjs) == '' mycss = link(_href=CDN_CSS.MARX) assert str(mycss) == '' - mycss = link(_rel="stylesheet", _href=CDN_JS.JQUERY_3_5_1) - assert str(mycss) == '' myimg = img(_src=CDN_IMG.PLACEHOLDER(100, 100)) assert str(myimg) == ''