Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
e3aee61
Adds klass and phor shorthands in README.md
nikalexis Aug 26, 2024
8bda6be
Adds template HTML tag
nikalexis Aug 26, 2024
d638901
Adds new directives (class, style, alpine, htmx) in dom_tag
nikalexis Aug 27, 2024
8237f5c
Makes some directives available in util.py
nikalexis Aug 27, 2024
b67abd7
Adds a new module all.py so you can import document, tags and utils a…
nikalexis Aug 27, 2024
f02baf3
Adds cssutils in setup.py
nikalexis Aug 27, 2024
6ae59f7
Adds dependencies in setup.cfg
nikalexis Aug 27, 2024
0a1697d
Adds readme docs for directives
nikalexis Aug 28, 2024
6a88b50
Include submodules
nikalexis Aug 28, 2024
9cf8ce1
Fix include
nikalexis Aug 28, 2024
a70b3db
Fix disabled_elt
nikalexis Sep 1, 2024
3bda795
Update readme
nikalexis Sep 1, 2024
750083f
Adds replace and exists functions on klass
nikalexis Sep 5, 2024
c1083f7
Adds support for inline directives
nikalexis Sep 10, 2024
c13c5af
Fix style directive direct set
nikalexis Sep 10, 2024
189116b
Adds element util function to retrive a new tag class object
nikalexis Sep 13, 2024
9b85cf5
Adds Space and Comma JoinerMixin
nikalexis Sep 25, 2024
fb1b600
Adds Substring directives
nikalexis Sep 26, 2024
8a470e2
Simplify modifier
nikalexis Sep 27, 2024
f07c92e
Adds string based manipulation on directives
nikalexis Sep 27, 2024
0f01d3e
Better classes naming
nikalexis Sep 27, 2024
a3d9741
Adds bool conversion for directives
nikalexis Sep 27, 2024
544f376
Makes tagname a class property object
nikalexis Sep 28, 2024
b3c4f6d
Adds orphan decorator and dom_tag function
nikalexis Sep 28, 2024
12a6722
Change ophan to container dom_tag type
nikalexis Sep 28, 2024
05df070
Updates README.md
nikalexis Sep 28, 2024
79dd336
Fixes readme
nikalexis Sep 30, 2024
1cbbaa2
Adds ability to orphan any element
nikalexis Sep 30, 2024
b35ce74
Adds is_orphan property
nikalexis Sep 30, 2024
9c5693e
Fix readme
nikalexis Sep 30, 2024
7673d9a
Fix orphan and adds doc on clas
nikalexis Oct 2, 2024
b0449f6
Adds modifiers decorator util
nikalexis Oct 3, 2024
f5957db
Fix modifier, separate instances after calling
nikalexis Oct 18, 2024
6eba73a
Adds inner function on dom_tag
nikalexis Oct 20, 2024
7287cd3
Returns boolean casting False, on empty containers or texts
nikalexis Oct 27, 2024
23e415e
Adds get_dom_tag
nikalexis Oct 28, 2024
79f77da
Adds hyperscript directive
nikalexis Oct 28, 2024
72cc75b
Fix modifier copying
nikalexis Oct 28, 2024
2e443f0
Adds delete on descriptor and modifier
nikalexis Oct 28, 2024
f56f6be
Adds keys on modifier
nikalexis Oct 28, 2024
c220907
Fix call modifier only when is set
nikalexis Oct 28, 2024
e76ea1a
Adds data and aria directives
nikalexis Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
412 changes: 412 additions & 0 deletions README.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions dominate/all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .document import document
from .tags import *
from .util import *
33 changes: 33 additions & 0 deletions dominate/directives/alpine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from .base import BaseAttributeDirective, BaseDominated
from .mixins.modifier import BaseAttributeModifierMixin


class AlpineDirective(BaseAttributeDirective):
prefix = 'x-'


class AlpineModifier(BaseAttributeModifierMixin, AlpineDirective):
pass


class AlpineDominated(BaseDominated):
default_directive = 'bind'

data = AlpineDirective()
init = AlpineDirective()
show = AlpineDirective()
bind = AlpineModifier()
on = AlpineModifier()
text = AlpineDirective()
html = AlpineDirective()
model = AlpineDirective()
modelable = AlpineDirective()
for_ = AlpineDirective()
transition = AlpineDirective()
effect = AlpineDirective()
ignore = AlpineDirective()
ref = AlpineDirective()
cloak = AlpineDirective()
teleport = AlpineDirective()
if_ = AlpineDirective()
id = AlpineDirective()
101 changes: 101 additions & 0 deletions dominate/directives/attrs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import cssutils

from .base import BaseAttributeDirective
from .mixins.delemeted_string import SpaceDelemetedStringListMixin
from .mixins.modifier import BaseAttributeModifierMixin


class KlassDirective(SpaceDelemetedStringListMixin, BaseAttributeDirective):
pass


class StyleDirective(BaseAttributeDirective):

encoding='utf-8'
normalize = True

@property
def css(self):
return cssutils.parseStyle(self.current_attr() or '', self.encoding)

@css.setter
def css(self, css):
super().__call__(css.getCssText(' '))

def reset_style(self, **properties):
return self.make_style(False, **properties)

def make_style(self, __include_current=True, __replace=True, __is_pythonic_key=True, **properties):
css = self.css if __include_current else cssutils.css.CSSStyleDeclaration()

for name, value in properties.items():
value, priority = value if type(value) is tuple else (value, '')

if __is_pythonic_key:
name = name.replace('_', '-')

css.setProperty(name, value, priority, self.normalize, __replace)

return css.getCssText(' ')

def reset(self, **properties):
return super().__call__(
self.reset_style(**properties)
)

def add(self, __replace=True, **properties):
return super().__call__(
self.make_style(True, __replace, **properties)
)

def add_extra(self, **properties):
return self.add(False, **properties)

def __add__(self, other):
return self.make_style(True, True, **other)

def __setitem__(self, key, value):
return super().__call__(
self.make_style(True, True, False, **{key: value})
)

def __set__(self, instance, value):
if type(value) is dict:
self.copied_self(instance).__call__(**value)
elif type(value) is cssutils.css.CSSStyleDeclaration:
super(StyleDirective, self.copied_self(instance)).__call__(value.getCssText(' '))
else:
super(StyleDirective, self.copied_self(instance)).__call__(value)

def remove_properties(self, *properties):
css = self.css

for name in properties:
css.removeProperty(name, self.normalize)

return css.getCssText(' ')

def remove(self, *properties):
return super().__call__(self.remove_properties(*properties))

def __delitem__(self, key):
return self.remove(key)

def __sub__(self, other):
if type(other) is str:
return self.remove_properties(other)
else:
return self.remove_properties(*other)

def __call__(self, **properties):
super().__call__(self.reset_style(**properties))


class DataDirective(BaseAttributeModifierMixin, BaseAttributeDirective):

separator = "-"


class AriaDirective(BaseAttributeModifierMixin, BaseAttributeDirective):

separator = "-"
87 changes: 87 additions & 0 deletions dominate/directives/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from .mixins.descriptor import DescriptorMixin
from .mixins.delemeted_string import DelemetedSubstringMixin


class BaseDominated(DescriptorMixin):

default_directive = None

def __getitem__(self, key):
if self.default_directive:
return getattr(self, self.default_directive)[key]
else:
raise NotImplementedError(f"`{self.__class__.__name__}` does not support a default directive.")

def __setitem__(self, key, value):
if self.default_directive:
return getattr(self, self.default_directive)[key](value)
else:
raise NotImplementedError(f"`{self.__class__.__name__}` does not support a default directive.")

def __call__(self, value):
if self.default_directive:
return getattr(self, self.default_directive)(value)
else:
raise NotImplementedError(f"`{self.__class__.__name__}` does not support a default directive.")


class BaseDirective(DescriptorMixin):

def prepend(self, string):
return self.__call__(
self.__radd__(string)
)

def append(self, string):
return self.__call__(
self.__add__(string)
)

def delete(self, raise_if_not_found=False):
try:
del self.get_dom_tag().attributes[self.full_directive()]
except:
if raise_if_not_found:
raise

def __add__(self, other):
return str(self) + other

def __radd__(self, other):
return other + str(self)

def __str__(self):
return self.current_attr() or ''

def __bool__(self):
return bool(str(self))


class BaseAttributeDirective(BaseDirective):

prefix = ''

@property
def directive(self):
return self.fixed_name

def full_directive(self):
return f"{self.prefix}{self.directive}"

def make_attr(self, value):
return {
self.full_directive(): value
}

def current_attr(self):
return self.get_dom_tag().attributes.get(self.full_directive(), None)

def __call__(self, value):
attributes = self.make_attr(value)
for a, v in attributes.items():
self.get_dom_tag().set_attribute(a, v, clean_pair=True)
return self.instance


class BaseDelemetedSubstringDirective(DelemetedSubstringMixin, BaseDirective):
pass
77 changes: 77 additions & 0 deletions dominate/directives/htmx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from .base import BaseAttributeDirective, BaseDelemetedSubstringDirective, BaseDominated
from .mixins.delemeted_string import CommaDelemetedStringListMixin, DelemetedStringDirectiveMixin, SpaceDelemetedStringListMixin
from .mixins.modifier import BaseAttributeModifierMixin


class HtmxAttributeDirective(BaseAttributeDirective):
prefix = 'hx-'


class HtmxAttributeModifier(BaseAttributeModifierMixin, HtmxAttributeDirective):
pass


class HtmxSpaceListAttributeDirective(SpaceDelemetedStringListMixin, HtmxAttributeDirective):
pass


class HtmxCommaListAttributeDirective(CommaDelemetedStringListMixin, HtmxAttributeDirective):
pass


class HtmxColonAttributeDirective(DelemetedStringDirectiveMixin, HtmxAttributeDirective):
JOIN_DELIMETER = SPLIT_DELIMETER = ':'


class HtmxSubstring(BaseDelemetedSubstringDirective):
pass


class HtmxCommaListSubstring(CommaDelemetedStringListMixin, HtmxSubstring):
pass


class HtmxSyncDirective(HtmxColonAttributeDirective):
selectors = HtmxCommaListSubstring()
strategy = HtmxSubstring()


class HtmxDominated(BaseDominated):
default_directive = 'on'

get = HtmxAttributeDirective()
post = HtmxAttributeDirective()
on = HtmxAttributeModifier()
push_url = HtmxAttributeDirective()
select = HtmxCommaListAttributeDirective()
select_oob = HtmxCommaListAttributeDirective()
swap = HtmxSpaceListAttributeDirective()
swap_oob = HtmxAttributeDirective()
target = HtmxAttributeDirective()
trigger = HtmxCommaListAttributeDirective()
vals = HtmxAttributeDirective()

boost = HtmxAttributeDirective()
confirm = HtmxAttributeDirective()
delete = HtmxAttributeDirective()
disable = HtmxAttributeDirective()
disabled_elt = HtmxCommaListAttributeDirective()
disinherit = HtmxSpaceListAttributeDirective()
encoding = HtmxAttributeDirective()
ext = HtmxCommaListAttributeDirective()
headers = HtmxAttributeDirective()
history = HtmxAttributeDirective()
history_elt = HtmxAttributeDirective()
include = HtmxCommaListAttributeDirective()
indicator = HtmxCommaListAttributeDirective()
inherit = HtmxSpaceListAttributeDirective()
params = HtmxCommaListAttributeDirective()
patch = HtmxAttributeDirective()
preserve = HtmxAttributeDirective()
prompt = HtmxAttributeDirective()
put = HtmxAttributeDirective()
replace_url = HtmxAttributeDirective()
request = HtmxAttributeDirective()
sync = HtmxSyncDirective()
validate = HtmxAttributeDirective()
vars = HtmxAttributeDirective()
11 changes: 11 additions & 0 deletions dominate/directives/hyperscript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .base import BaseAttributeDirective, BaseDominated


class HyperscriptDirective(BaseAttributeDirective):
pass


class HyperscriptDominated(BaseDominated):
default_directive = 'script'

script = HyperscriptDirective()
Loading