djhtmx 1.2.6__tar.gz → 1.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {djhtmx-1.2.6 → djhtmx-1.2.8}/CHANGELOG.md +10 -0
  2. {djhtmx-1.2.6 → djhtmx-1.2.8}/PKG-INFO +1 -1
  3. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/__init__.py +1 -1
  4. djhtmx-1.2.8/src/djhtmx/static/htmx/2.0.4/ext/idiomorph-ext.min.js +1 -0
  5. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/templatetags/htmx.py +7 -3
  6. {djhtmx-1.2.6 → djhtmx-1.2.8}/.gitignore +0 -0
  7. {djhtmx-1.2.6 → djhtmx-1.2.8}/LICENSE +0 -0
  8. {djhtmx-1.2.6 → djhtmx-1.2.8}/MANIFEST.in +0 -0
  9. {djhtmx-1.2.6 → djhtmx-1.2.8}/README.md +0 -0
  10. {djhtmx-1.2.6 → djhtmx-1.2.8}/pyproject.toml +0 -0
  11. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/apps.py +0 -0
  12. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/command_queue.py +0 -0
  13. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/commands.py +0 -0
  14. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/component.py +0 -0
  15. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/consumer.py +0 -0
  16. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/context.py +0 -0
  17. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/exceptions.py +0 -0
  18. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/global_events.py +0 -0
  19. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/introspection.py +0 -0
  20. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/json.py +0 -0
  21. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/management/commands/htmx.py +0 -0
  22. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/middleware.py +0 -0
  23. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/query.py +0 -0
  24. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/repo.py +0 -0
  25. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/settings.py +0 -0
  26. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/ext/ws.js +0 -0
  27. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.amd.js +0 -0
  28. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.cjs.js +0 -0
  29. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.esm.d.ts +0 -0
  30. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.esm.js +0 -0
  31. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.js +0 -0
  32. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/2.0.4/htmx.min.js +0 -0
  33. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/static/htmx/django.js +0 -0
  34. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/templates/htmx/headers.html +0 -0
  35. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/templates/htmx/lazy.html +0 -0
  36. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/templatetags/__init__.py +0 -0
  37. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/testing.py +0 -0
  38. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/tracing.py +0 -0
  39. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/urls.py +0 -0
  40. {djhtmx-1.2.6 → djhtmx-1.2.8}/src/djhtmx/utils.py +0 -0
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.8] - 2026-01-06
11
+
12
+ ### Added
13
+ - Added idiomorph extension (idiomorph-ext.min.js) for HTMX 2.0.4
14
+
15
+ ## [1.2.7] - 2026-01-05
16
+
17
+ ### Changed
18
+ - The `htmx` template tag now accepts component types directly as the first parameter, automatically extracting the component name. You can now use `{% htmx MyComponent data=value %}` instead of `{% htmx 'MyComponent' data=value %}`
19
+
10
20
  ## [1.2.6] - 2025-12-24
11
21
 
12
22
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: djhtmx
3
- Version: 1.2.6
3
+ Version: 1.2.8
4
4
  Summary: Interactive UI Components for Django using HTMX
5
5
  Project-URL: Homepage, https://github.com/edelvalle/djhtmx
6
6
  Project-URL: Documentation, https://github.com/edelvalle/djhtmx#readme
@@ -1,4 +1,4 @@
1
1
  from .middleware import middleware
2
2
 
3
- __version__ = "1.2.6"
3
+ __version__ = "1.2.8"
4
4
  __all__ = ("middleware",)
@@ -0,0 +1 @@
1
+ var Idiomorph=function(){"use strict";const e=()=>{};const n={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:e=>e.getAttribute("im-preserve")==="true",shouldReAppend:e=>e.getAttribute("im-re-append")==="true",shouldRemove:e,afterHeadMorphed:e},restoreFocus:true};function t(t,e,n={}){t=d(t);const r=f(e);const i=c(t,r,n);const o=a(i,()=>{return u(i,t,r,e=>{if(e.morphStyle==="innerHTML"){s(e,t,r);return Array.from(t.childNodes)}else{return l(e,t,r)}})});i.pantry.remove();return o}function l(e,t,n){const r=f(t);s(e,r,n,t,t.nextSibling);return Array.from(r.childNodes)}function a(e,t){if(!e.config.restoreFocus)return t();let n=document.activeElement;if(!(n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement)){return t()}const{id:r,selectionStart:i,selectionEnd:o}=n;const l=t();if(r&&r!==document.activeElement?.getAttribute("id")){n=e.target.querySelector(`[id="${r}"]`);n?.focus()}if(n&&!n.selectionEnd&&o){n.setSelectionRange(i,o)}return l}const s=function(){function e(e,t,n,r=null,i=null){if(t instanceof HTMLTemplateElement&&n instanceof HTMLTemplateElement){t=t.content;n=n.content}r||=t.firstChild;for(const o of n.childNodes){if(r&&r!=i){const a=f(e,o,r,i);if(a){if(a!==r){h(e,r,a)}b(a,o,e);r=a.nextSibling;continue}}if(o instanceof Element){const s=o.getAttribute("id");if(e.persistentIds.has(s)){const u=p(t,s,r,e);b(u,o,e);r=u.nextSibling;continue}}const l=d(t,o,r,e);if(l){r=l.nextSibling}}while(r&&r!=i){const c=r;r=r.nextSibling;m(e,c)}}function d(e,t,n,r){if(r.callbacks.beforeNodeAdded(t)===false)return null;if(r.idMap.has(t)){const i=document.createElement(t.tagName);e.insertBefore(i,n);b(i,t,r);r.callbacks.afterNodeAdded(i);return i}else{const o=document.importNode(t,true);e.insertBefore(o,n);r.callbacks.afterNodeAdded(o);return o}}const f=function(){function e(e,t,n,r){let i=null;let o=t.nextSibling;let l=0;let a=n;while(a&&a!=r){if(u(a,t)){if(s(e,a,t)){return a}if(i===null){if(!e.idMap.has(a)){i=a}}}if(i===null&&o&&u(a,o)){l++;o=o.nextSibling;if(l>=2){i=undefined}}if(e.activeElementAndParents.includes(a))break;a=a.nextSibling}return i||null}function s(e,t,n){let r=e.idMap.get(t);let i=e.idMap.get(n);if(!i||!r)return false;for(const o of r){if(i.has(o)){return true}}return false}function u(e,t){const n=e;const r=t;return n.nodeType===r.nodeType&&n.tagName===r.tagName&&(!n.getAttribute?.("id")||n.getAttribute?.("id")===r.getAttribute?.("id"))}return e}();function m(e,t){if(e.idMap.has(t)){l(e.pantry,t,null)}else{if(e.callbacks.beforeNodeRemoved(t)===false)return;t.parentNode?.removeChild(t);e.callbacks.afterNodeRemoved(t)}}function h(t,e,n){let r=e;while(r&&r!==n){let e=r;r=r.nextSibling;m(t,e)}return r}function p(e,t,n,r){const i=r.target.getAttribute?.("id")===t&&r.target||r.target.querySelector(`[id="${t}"]`)||r.pantry.querySelector(`[id="${t}"]`);o(i,r);l(e,i,n);return i}function o(t,n){const r=t.getAttribute("id");while(t=t.parentNode){let e=n.idMap.get(t);if(e){e.delete(r);if(!e.size){n.idMap.delete(t)}}}}function l(t,n,r){if(t.moveBefore){try{t.moveBefore(n,r)}catch(e){t.insertBefore(n,r)}}else{t.insertBefore(n,r)}}return e}();const b=function(){function e(e,t,n){if(n.ignoreActive&&e===document.activeElement){return null}if(n.callbacks.beforeNodeMorphed(e,t)===false){return e}if(e instanceof HTMLHeadElement&&n.head.ignore){}else if(e instanceof HTMLHeadElement&&n.head.style!=="morph"){m(e,t,n)}else{r(e,t,n);if(!f(e,n)){s(n,e,t)}}n.callbacks.afterNodeMorphed(e,t);return e}function r(e,t,n){let r=t.nodeType;if(r===1){const i=e;const o=t;const l=i.attributes;const a=o.attributes;for(const s of a){if(d(s.name,i,"update",n)){continue}if(i.getAttribute(s.name)!==s.value){i.setAttribute(s.name,s.value)}}for(let e=l.length-1;0<=e;e--){const u=l[e];if(!u)continue;if(!o.hasAttribute(u.name)){if(d(u.name,i,"remove",n)){continue}i.removeAttribute(u.name)}}if(!f(i,n)){c(i,o,n)}}if(r===8||r===3){if(e.nodeValue!==t.nodeValue){e.nodeValue=t.nodeValue}}}function c(n,r,i){if(n instanceof HTMLInputElement&&r instanceof HTMLInputElement&&r.type!=="file"){let e=r.value;let t=n.value;o(n,r,"checked",i);o(n,r,"disabled",i);if(!r.hasAttribute("value")){if(!d("value",n,"remove",i)){n.value="";n.removeAttribute("value")}}else if(t!==e){if(!d("value",n,"update",i)){n.setAttribute("value",e);n.value=e}}}else if(n instanceof HTMLOptionElement&&r instanceof HTMLOptionElement){o(n,r,"selected",i)}else if(n instanceof HTMLTextAreaElement&&r instanceof HTMLTextAreaElement){let e=r.value;let t=n.value;if(d("value",n,"update",i)){return}if(e!==t){n.value=e}if(n.firstChild&&n.firstChild.nodeValue!==e){n.firstChild.nodeValue=e}}}function o(e,t,n,r){const i=t[n],o=e[n];if(i!==o){const l=d(n,e,"update",r);if(!l){e[n]=t[n]}if(i){if(!l){e.setAttribute(n,"")}}else{if(!d(n,e,"remove",r)){e.removeAttribute(n)}}}}function d(e,t,n,r){if(e==="value"&&r.ignoreActiveValue&&t===document.activeElement){return true}return r.callbacks.beforeAttributeUpdated(e,t,n)===false}function f(e,t){return!!t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}return e}();function u(t,e,n,r){if(t.head.block){const i=e.querySelector("head");const o=n.querySelector("head");if(i&&o){const l=m(i,o,t);return Promise.all(l).then(()=>{const e=Object.assign(t,{head:{block:false,ignore:true}});return r(e)})}}return r(t)}function m(e,t,r){let i=[];let o=[];let l=[];let a=[];let s=new Map;for(const n of t.children){s.set(n.outerHTML,n)}for(const c of e.children){let e=s.has(c.outerHTML);let t=r.head.shouldReAppend(c);let n=r.head.shouldPreserve(c);if(e||n){if(t){o.push(c)}else{s.delete(c.outerHTML);l.push(c)}}else{if(r.head.style==="append"){if(t){o.push(c);a.push(c)}}else{if(r.head.shouldRemove(c)!==false){o.push(c)}}}}a.push(...s.values());let u=[];for(const d of a){let n=document.createRange().createContextualFragment(d.outerHTML).firstChild;if(r.callbacks.beforeNodeAdded(n)!==false){if("href"in n&&n.href||"src"in n&&n.src){let t;let e=new Promise(function(e){t=e});n.addEventListener("load",function(){t()});u.push(e)}e.appendChild(n);r.callbacks.afterNodeAdded(n);i.push(n)}}for(const f of o){if(r.callbacks.beforeNodeRemoved(f)!==false){e.removeChild(f);r.callbacks.afterNodeRemoved(f)}}r.head.afterHeadMorphed(e,{added:i,kept:l,removed:o});return u}const c=function(){function e(e,t,n){const{persistentIds:r,idMap:i}=f(e,t);const o=a(n);const l=o.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(l)){throw`Do not understand how to morph style ${l}`}return{target:e,newContent:t,config:o,morphStyle:l,ignoreActive:o.ignoreActive,ignoreActiveValue:o.ignoreActiveValue,restoreFocus:o.restoreFocus,idMap:i,persistentIds:r,pantry:s(),activeElementAndParents:u(e),callbacks:o.callbacks,head:o.head}}function a(e){let t=Object.assign({},n);Object.assign(t,e);t.callbacks=Object.assign({},n.callbacks,e.callbacks);t.head=Object.assign({},n.head,e.head);return t}function s(){const e=document.createElement("div");e.hidden=true;document.body.insertAdjacentElement("afterend",e);return e}function u(e){let t=[];let n=document.activeElement;if(n?.tagName!=="BODY"&&e.contains(n)){while(n){t.push(n);if(n===e)break;n=n.parentElement}}return t}function c(e){let t=Array.from(e.querySelectorAll("[id]"));if(e.getAttribute?.("id")){t.push(e)}return t}function d(n,e,r,t){for(const i of t){const o=i.getAttribute("id");if(e.has(o)){let t=i;while(t){let e=n.get(t);if(e==null){e=new Set;n.set(t,e)}e.add(o);if(t===r)break;t=t.parentElement}}}}function f(e,t){const n=c(e);const r=c(t);const i=m(n,r);let o=new Map;d(o,i,e,n);const l=t.__idiomorphRoot||t;d(o,i,l,r);return{persistentIds:i,idMap:o}}function m(e,t){let n=new Set;let r=new Map;for(const{id:o,tagName:l}of e){if(r.has(o)){n.add(o)}else{r.set(o,l)}}let i=new Set;for(const{id:o,tagName:l}of t){if(i.has(o)){n.add(o)}else if(r.get(o)===l){i.add(o)}}for(const o of n){i.delete(o)}return i}return e}();const{normalizeElement:d,normalizeParent:f}=function(){const i=new WeakSet;function e(e){if(e instanceof Document){return e.documentElement}else{return e}}function r(e){if(e==null){return document.createElement("div")}else if(typeof e==="string"){return r(l(e))}else if(i.has(e)){return e}else if(e instanceof Node){if(e.parentNode){return new o(e)}else{const t=document.createElement("div");t.append(e);return t}}else{const t=document.createElement("div");for(const n of[...e]){t.append(n)}return t}}class o{constructor(e){this.originalNode=e;this.realParentNode=e.parentNode;this.previousSibling=e.previousSibling;this.nextSibling=e.nextSibling}get childNodes(){const e=[];let t=this.previousSibling?this.previousSibling.nextSibling:this.realParentNode.firstChild;while(t&&t!=this.nextSibling){e.push(t);t=t.nextSibling}return e}querySelectorAll(r){return this.childNodes.reduce((t,e)=>{if(e instanceof Element){if(e.matches(r))t.push(e);const n=e.querySelectorAll(r);for(let e=0;e<n.length;e++){t.push(n[e])}}return t},[])}insertBefore(e,t){return this.realParentNode.insertBefore(e,t)}moveBefore(e,t){return this.realParentNode.moveBefore(e,t)}get __idiomorphRoot(){return this.originalNode}}function l(n){let r=new DOMParser;let e=n.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(e.match(/<\/html>/)||e.match(/<\/head>/)||e.match(/<\/body>/)){let t=r.parseFromString(n,"text/html");if(e.match(/<\/html>/)){i.add(t);return t}else{let e=t.firstChild;if(e){i.add(e)}return e}}else{let e=r.parseFromString("<body><template>"+n+"</template></body>","text/html");let t=e.body.querySelector("template").content;i.add(t);return t}}return{normalizeElement:e,normalizeParent:r}}();return{morph:t,defaults:n}}();(function(){function i(e){if(e==="morph"||e==="morph:outerHTML"){return{morphStyle:"outerHTML"}}else if(e==="morph:innerHTML"){return{morphStyle:"innerHTML"}}else if(e.startsWith("morph:")){return Function("return ("+e.slice(6)+")")()}}htmx.defineExtension("morph",{isInlineSwap:function(e){let t=i(e);return t?.morphStyle==="outerHTML"||t?.morphStyle==null},handleSwap:function(e,t,n){let r=i(e);if(r){return Idiomorph.morph(t,n.children,r)}}})})();
@@ -73,7 +73,7 @@ def add_delay_jitter(event, arg=None):
73
73
  @register.simple_tag(takes_context=True)
74
74
  def htmx(
75
75
  context,
76
- _name: str,
76
+ _name: str | type[HtmxComponent],
77
77
  _state: dict[str, Any] | None = None,
78
78
  *,
79
79
  lazy: Literal["once"] | bool = False,
@@ -81,12 +81,16 @@ def htmx(
81
81
  ):
82
82
  """Inserts an HTMX Component.
83
83
 
84
- Pass the component name and the initial state:
84
+ Pass the component name (as a string) or component type, and the initial state:
85
85
 
86
86
  ```html
87
87
  {% htmx 'AmazinData' data=some_data %}
88
+ {% htmx MyComponent data=some_data %}
88
89
  ```
89
90
  """
91
+ # Extract component name if a type is passed
92
+ component_name = _name.__name__ if isinstance(_name, type) else _name
93
+
90
94
  state = (_state or {}) | state
91
95
  repo: Repository = context["htmx_repo"]
92
96
  state |= {"lazy": lazy is True}
@@ -94,7 +98,7 @@ def htmx(
94
98
  # Extract parent component ID from context if available
95
99
  parent_id = getattr(context.get("this"), "id", None)
96
100
 
97
- component = repo.build(_name, state, parent_id=parent_id)
101
+ component = repo.build(component_name, state, parent_id=parent_id)
98
102
  return repo.render_html(
99
103
  component,
100
104
  lazy=lazy if isinstance(lazy, bool) else False,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes