djhtmx 1.2.8__py3-none-any.whl → 1.2.9__py3-none-any.whl

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.
djhtmx/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .middleware import middleware
2
2
 
3
- __version__ = "1.2.8"
3
+ __version__ = "1.2.9"
4
4
  __all__ = ("middleware",)
djhtmx/command_queue.py CHANGED
@@ -16,6 +16,7 @@ from .component import (
16
16
  Open,
17
17
  Redirect,
18
18
  Render,
19
+ ScrollIntoView,
19
20
  Signal,
20
21
  SkipRender,
21
22
  )
@@ -86,6 +87,7 @@ class CommandQueue:
86
87
  | Emit()
87
88
  | SkipRender()
88
89
  | Focus()
90
+ | ScrollIntoView()
89
91
  | Redirect()
90
92
  | DispatchDOMEvent()
91
93
  | Open()
@@ -139,7 +141,15 @@ class CommandQueue:
139
141
  return 6, component.id, timestamp
140
142
  else:
141
143
  return 7, component.id, timestamp
142
- case Focus() | Redirect() | DispatchDOMEvent() | Open() | ReplaceURL() | PushURL():
144
+ case (
145
+ Focus()
146
+ | ScrollIntoView()
147
+ | Redirect()
148
+ | DispatchDOMEvent()
149
+ | Open()
150
+ | ReplaceURL()
151
+ | PushURL()
152
+ ):
143
153
  return 8, "", 0
144
154
  case _ as unreachable:
145
155
  assert_never(unreachable)
djhtmx/component.py CHANGED
@@ -89,6 +89,16 @@ class Focus:
89
89
  command: Literal["focus"] = "focus"
90
90
 
91
91
 
92
+ @dataclass(slots=True)
93
+ class ScrollIntoView:
94
+ "Scrolls the browser element that matches `selector` into view"
95
+
96
+ selector: str
97
+ behavior: Literal["auto", "smooth", "instant"] = "smooth"
98
+ block: Literal["start", "center", "end", "nearest"] = "center"
99
+ command: Literal["scroll_into_view"] = "scroll_into_view"
100
+
101
+
92
102
  @dataclass(slots=True)
93
103
  class Execute:
94
104
  component_id: str
@@ -126,34 +136,62 @@ class BuildAndRender:
126
136
 
127
137
  @classmethod
128
138
  def append(
129
- cls, target_: str, component_: type[HtmxComponent], parent_id: str | None = None, **state
139
+ cls,
140
+ target_: str,
141
+ component_: type[HtmxComponent],
142
+ parent_id: str | None = None,
143
+ **state,
130
144
  ):
131
145
  return cls(
132
- component=component_, state=state, oob=f"beforeend: {target_}", parent_id=parent_id
146
+ component=component_,
147
+ state=state,
148
+ oob=f"beforeend: {target_}",
149
+ parent_id=parent_id,
133
150
  )
134
151
 
135
152
  @classmethod
136
153
  def prepend(
137
- cls, target_: str, component_: type[HtmxComponent], parent_id: str | None = None, **state
154
+ cls,
155
+ target_: str,
156
+ component_: type[HtmxComponent],
157
+ parent_id: str | None = None,
158
+ **state,
138
159
  ):
139
160
  return cls(
140
- component=component_, state=state, oob=f"afterbegin: {target_}", parent_id=parent_id
161
+ component=component_,
162
+ state=state,
163
+ oob=f"afterbegin: {target_}",
164
+ parent_id=parent_id,
141
165
  )
142
166
 
143
167
  @classmethod
144
168
  def after(
145
- cls, target_: str, component_: type[HtmxComponent], parent_id: str | None = None, **state
169
+ cls,
170
+ target_: str,
171
+ component_: type[HtmxComponent],
172
+ parent_id: str | None = None,
173
+ **state,
146
174
  ):
147
175
  return cls(
148
- component=component_, state=state, oob=f"afterend: {target_}", parent_id=parent_id
176
+ component=component_,
177
+ state=state,
178
+ oob=f"afterend: {target_}",
179
+ parent_id=parent_id,
149
180
  )
150
181
 
151
182
  @classmethod
152
183
  def before(
153
- cls, target_: str, component_: type[HtmxComponent], parent_id: str | None = None, **state
184
+ cls,
185
+ target_: str,
186
+ component_: type[HtmxComponent],
187
+ parent_id: str | None = None,
188
+ **state,
154
189
  ):
155
190
  return cls(
156
- component=component_, state=state, oob=f"beforebegin: {target_}", parent_id=parent_id
191
+ component=component_,
192
+ state=state,
193
+ oob=f"beforebegin: {target_}",
194
+ parent_id=parent_id,
157
195
  )
158
196
 
159
197
  @classmethod
@@ -191,6 +229,7 @@ Command = (
191
229
  Destroy
192
230
  | Redirect
193
231
  | Focus
232
+ | ScrollIntoView
194
233
  | DispatchDOMEvent
195
234
  | SkipRender
196
235
  | BuildAndRender
@@ -249,7 +288,10 @@ def get_template(template: str) -> RenderFunction: # pragma: no cover
249
288
  return cast(RenderFunction, _compose(loader.get_template(template).render, mark_safe))
250
289
  else:
251
290
  if (render := RENDER_FUNC.get(template)) is None:
252
- render = cast(RenderFunction, _compose(loader.get_template(template).render, mark_safe))
291
+ render = cast(
292
+ RenderFunction,
293
+ _compose(loader.get_template(template).render, mark_safe),
294
+ )
253
295
  RENDER_FUNC[template] = render
254
296
  return render
255
297
 
djhtmx/consumer.py CHANGED
@@ -6,7 +6,7 @@ from pydantic import BaseModel, TypeAdapter
6
6
 
7
7
  from . import json
8
8
  from .commands import PushURL, ReplaceURL, SendHtml
9
- from .component import Command, Destroy, DispatchDOMEvent, Focus, Open, Redirect
9
+ from .component import Command, Destroy, DispatchDOMEvent, Focus, Open, Redirect, ScrollIntoView
10
10
  from .introspection import parse_request_data
11
11
  from .repo import Repository
12
12
  from .utils import get_params
@@ -58,6 +58,7 @@ class Consumer(AsyncJsonWebsocketConsumer):
58
58
  Destroy()
59
59
  | Redirect()
60
60
  | Focus()
61
+ | ScrollIntoView()
61
62
  | DispatchDOMEvent()
62
63
  | PushURL()
63
64
  | Open()
djhtmx/repo.py CHANGED
@@ -35,6 +35,7 @@ from .component import (
35
35
  Open,
36
36
  Redirect,
37
37
  Render,
38
+ ScrollIntoView,
38
39
  Signal,
39
40
  SkipRender,
40
41
  _get_query_patchers,
@@ -56,7 +57,15 @@ logger = logging.getLogger(__name__)
56
57
 
57
58
 
58
59
  ProcessedCommand = (
59
- Destroy | Redirect | Open | Focus | DispatchDOMEvent | SendHtml | PushURL | ReplaceURL
60
+ Destroy
61
+ | Redirect
62
+ | Open
63
+ | Focus
64
+ | ScrollIntoView
65
+ | DispatchDOMEvent
66
+ | SendHtml
67
+ | PushURL
68
+ | ReplaceURL
60
69
  )
61
70
 
62
71
 
@@ -296,6 +305,7 @@ class Repository:
296
305
  | PushURL()
297
306
  | Redirect()
298
307
  | Focus()
308
+ | ScrollIntoView()
299
309
  | DispatchDOMEvent() as command
300
310
  ):
301
311
  commands.processing_component_id = ""
@@ -1,197 +1,221 @@
1
- (function () {
2
- // WebSocket Management
3
- let sentComponents = new Set();
4
-
5
- function sendRemovedComponents(event) {
6
- let removedComponents = Array.from(sentComponents).filter(
7
- (id) => !document.getElementById(id),
8
- );
9
- removedComponents.forEach((id) => sentComponents.delete(id));
10
- if (removedComponents.length) {
11
- event.detail.socketWrapper.send(
12
- JSON.stringify({
13
- type: "removed",
14
- component_ids: removedComponents,
15
- }),
16
- );
17
- }
18
- }
19
-
20
- function sendAddedComponents(event) {
21
- let states = [];
22
- let subscriptions = new Map();
23
- let ids = new Set();
24
-
25
- Array.from(document.querySelectorAll("[data-hx-state]"))
26
- .filter((el) => !sentComponents.has(el.id))
27
- .forEach((element) => {
28
- let hxSubscriptions = element.dataset.hxSubscriptions;
29
- if (hxSubscriptions !== undefined) {
30
- subscriptions[element.id] = element.dataset.hxSubscriptions;
31
- }
32
- states.push(element.dataset.hxState);
33
- ids.add(element.id);
34
- });
35
- ids.forEach((id) => sentComponents.add(id));
36
-
37
- if (ids.size) {
38
- event.detail.socketWrapper.send(
39
- JSON.stringify({
40
- type: "added",
41
- states,
42
- subscriptions,
43
- }),
44
- );
45
- }
46
- }
47
-
48
- function removeHtmxIndicator() {
49
- // remove indicator
50
- document
51
- .querySelectorAll(".htmx-request")
52
- .forEach((el) => el.classList.remove("htmx-request"));
53
- }
54
-
55
- document.addEventListener("htmx:wsOpen", (event) => {
56
- console.log("OPEN", event);
57
- sentComponents.clear();
58
- removeHtmxIndicator();
59
- });
60
-
61
- document.addEventListener("htmx:wsClose", (event) => {
62
- console.log("CLOSE", event);
63
- sentComponents.clear();
64
- removeHtmxIndicator();
65
- });
66
-
67
- document.addEventListener("htmx:wsConfigSend", (event) => {
68
- // add indicator
69
- let indicatorSelector = event.detail.elt
70
- .closest("[hx-indicator]")
71
- ?.getAttribute("hx-indicator");
72
- if (indicatorSelector) {
73
- document
74
- .querySelectorAll(indicatorSelector)
75
- .forEach((el) => el.classList.add("htmx-request"));
76
- }
77
-
78
- // send current state
79
- sendRemovedComponents(event);
80
- sendAddedComponents(event);
81
-
82
- // enrich event message
83
- event.detail.headers["HX-Component-Id"] =
84
- event.detail.elt.closest("[data-hx-state]").id;
85
- event.detail.headers["HX-Component-Handler"] =
86
- event.detail.elt.getAttribute("ws-send");
87
- });
88
-
89
- document.addEventListener("htmx:wsBeforeMessage", (event) => {
90
- removeHtmxIndicator();
91
-
92
- // process message
93
- if (event.detail.message.startsWith("{")) {
94
- let commandData = JSON.parse(event.detail.message);
95
- event.preventDefault();
96
- let { command } = commandData;
97
- switch (command) {
98
- case "destroy": {
99
- let { component_id } = commandData;
100
- document.getElementById(component_id)?.remove();
101
- break;
102
- }
103
- case "focus": {
104
- let { selector } = commandData;
105
- document.querySelector(selector)?.focus();
106
- break;
107
- }
108
- case "redirect": {
109
- let { url } = commandData;
110
- location.assign(url);
111
- break;
112
- }
113
- case "dispatch_event": {
114
- let = { target, detail, buubles, cancelable, composed } =
115
- commandData;
116
- document.querySelector(target)?.dispatchEvent(
117
- new CustomEvent(event, {
118
- detail,
119
- buubles,
120
- cancelable,
121
- composed,
122
- }),
123
- );
124
- break;
125
- }
126
- case "send_state": {
127
- let { component_id, state } = commandData;
128
- let component = document.getElementById(component_id);
129
- if (component) {
130
- component.dataset.hxState = state;
131
- }
132
- break;
133
- }
134
- case "push_url": {
135
- let { url } = commandData;
136
- history.pushState({}, document.title, url);
137
- break;
138
- }
139
-
140
- default:
141
- console.error(
142
- "Can't process command:",
143
- event.detail.message,
144
- );
145
- break;
146
- }
147
- }
148
- });
149
-
150
- document.addEventListener("hxDispatchDOMEvent", (event) => {
151
- event.detail.value.map(
152
- ({ event, target, detail, bubbles, cancelable, composed }) => {
153
- let el = document.querySelector(target);
154
- if (typeof el != "undefined" && el != null) {
155
- // This setTimeout basically queues the dispatch of the event
156
- // to avoid dispatching events within events handlers.
157
- setTimeout(
158
- () =>
159
- el.dispatchEvent(
160
- new CustomEvent(event, {
161
- detail,
162
- bubbles,
163
- cancelable,
164
- composed,
165
- }),
166
- ),
167
- 0,
168
- );
169
- }
170
- },
171
- );
172
- });
173
-
174
- document.addEventListener("hxFocus", (event) => {
175
- event.detail.value.map((selector) => {
176
- document.querySelector(selector).focus();
177
- });
178
- });
179
-
180
- document.addEventListener("hxOpenURL", (event) => {
181
- event.detail.value.map(({ url, name, target, rel }) => {
182
- const link = document.createElement('a');
183
- link.href = url;
184
- link.target = !!target ? target : '_blank';
185
- if (name) {
186
- link.download = name;
187
- }
188
- if (rel) {
189
- link.rel = rel;
190
- }
191
- link.click();
192
- });
193
- });
194
-
1
+ (() => {
2
+ // WebSocket Management
3
+ const sentComponents = new Set();
4
+
5
+ function sendRemovedComponents(event) {
6
+ const removedComponents = Array.from(sentComponents).filter(
7
+ (id) => !document.getElementById(id),
8
+ );
9
+ for (const id of removedComponents) {
10
+ sentComponents.delete(id);
11
+ }
12
+ if (removedComponents.length) {
13
+ event.detail.socketWrapper.send(
14
+ JSON.stringify({
15
+ type: "removed",
16
+ component_ids: removedComponents,
17
+ }),
18
+ );
19
+ }
20
+ }
21
+
22
+ function sendAddedComponents(event) {
23
+ const states = [];
24
+ const subscriptions = new Map();
25
+ const ids = new Set();
26
+
27
+ for (const element of Array.from(
28
+ document.querySelectorAll("[data-hx-state]"),
29
+ ).filter((el) => !sentComponents.has(el.id))) {
30
+ const hxSubscriptions = element.dataset.hxSubscriptions;
31
+ if (hxSubscriptions !== undefined) {
32
+ subscriptions[element.id] = element.dataset.hxSubscriptions;
33
+ }
34
+ states.push(element.dataset.hxState);
35
+ ids.add(element.id);
36
+ }
37
+ for (const id of ids) {
38
+ sentComponents.add(id);
39
+ }
40
+
41
+ if (ids.size) {
42
+ event.detail.socketWrapper.send(
43
+ JSON.stringify({
44
+ type: "added",
45
+ states,
46
+ subscriptions,
47
+ }),
48
+ );
49
+ }
50
+ }
51
+
52
+ function removeHtmxIndicator() {
53
+ // remove indicator
54
+ for (const el of document.querySelectorAll(".htmx-request")) {
55
+ el.classList.remove("htmx-request");
56
+ }
57
+ }
58
+
59
+ document.addEventListener("htmx:wsOpen", (event) => {
60
+ console.log("OPEN", event);
61
+ sentComponents.clear();
62
+ removeHtmxIndicator();
63
+ });
64
+
65
+ document.addEventListener("htmx:wsClose", (event) => {
66
+ console.log("CLOSE", event);
67
+ sentComponents.clear();
68
+ removeHtmxIndicator();
69
+ });
70
+
71
+ document.addEventListener("htmx:wsConfigSend", (event) => {
72
+ // add indicator
73
+ const indicatorSelector = event.detail.elt
74
+ .closest("[hx-indicator]")
75
+ ?.getAttribute("hx-indicator");
76
+ if (indicatorSelector) {
77
+ for (const el of document.querySelectorAll(indicatorSelector)) {
78
+ el.classList.add("htmx-request");
79
+ }
80
+ }
81
+
82
+ // send current state
83
+ sendRemovedComponents(event);
84
+ sendAddedComponents(event);
85
+
86
+ // enrich event message
87
+ event.detail.headers["HX-Component-Id"] =
88
+ event.detail.elt.closest("[data-hx-state]").id;
89
+ event.detail.headers["HX-Component-Handler"] =
90
+ event.detail.elt.getAttribute("ws-send");
91
+ });
92
+
93
+ document.addEventListener("htmx:wsBeforeMessage", (event) => {
94
+ removeHtmxIndicator();
95
+
96
+ // process message
97
+ if (event.detail.message.startsWith("{")) {
98
+ const commandData = JSON.parse(event.detail.message);
99
+ event.preventDefault();
100
+ const { command } = commandData;
101
+ switch (command) {
102
+ case "destroy": {
103
+ const { component_id } = commandData;
104
+ document.getElementById(component_id)?.remove();
105
+ break;
106
+ }
107
+ case "focus": {
108
+ const { selector } = commandData;
109
+ document.querySelector(selector)?.focus();
110
+ break;
111
+ }
112
+ case "scroll_into_view": {
113
+ const { selector, behavior = "smooth", block = "center" } = commandData;
114
+ document.querySelector(selector)?.scrollIntoView({
115
+ behavior,
116
+ block,
117
+ });
118
+ break;
119
+ }
120
+ case "redirect": {
121
+ const { url } = commandData;
122
+ location.assign(url);
123
+ break;
124
+ }
125
+ case "dispatch_event": {
126
+ const { target, detail, buubles, cancelable, composed } = commandData;
127
+ document.querySelector(target)?.dispatchEvent(
128
+ new CustomEvent(event, {
129
+ detail,
130
+ buubles,
131
+ cancelable,
132
+ composed,
133
+ }),
134
+ );
135
+ break;
136
+ }
137
+ case "send_state": {
138
+ const { component_id, state } = commandData;
139
+ const component = document.getElementById(component_id);
140
+ if (component) {
141
+ component.dataset.hxState = state;
142
+ }
143
+ break;
144
+ }
145
+ case "push_url": {
146
+ const { url } = commandData;
147
+ history.pushState({}, document.title, url);
148
+ break;
149
+ }
150
+
151
+ default:
152
+ console.error("Can't process command:", event.detail.message);
153
+ break;
154
+ }
155
+ }
156
+ });
157
+
158
+ document.addEventListener("hxDispatchDOMEvent", (event) => {
159
+ for (const {
160
+ event: eventName,
161
+ target,
162
+ detail,
163
+ bubbles,
164
+ cancelable,
165
+ composed,
166
+ } of event.detail.value) {
167
+ const el = document.querySelector(target);
168
+ if (el) {
169
+ // This setTimeout basically queues the dispatch of the event
170
+ // to avoid dispatching events within events handlers.
171
+ setTimeout(
172
+ () =>
173
+ el.dispatchEvent(
174
+ new CustomEvent(eventName, {
175
+ detail,
176
+ bubbles,
177
+ cancelable,
178
+ composed,
179
+ }),
180
+ ),
181
+ 0,
182
+ );
183
+ }
184
+ }
185
+ });
186
+
187
+ document.addEventListener("hxFocus", (event) => {
188
+ for (const selector of event.detail.value) {
189
+ document.querySelector(selector).focus();
190
+ }
191
+ });
192
+
193
+ document.addEventListener("hxScrollIntoView", (event) => {
194
+ for (const item of event.detail.value) {
195
+ const selector = typeof item === "string" ? item : item.selector;
196
+ const behavior = typeof item === "object" ? item.behavior || "smooth" : "smooth";
197
+ const block = typeof item === "object" ? item.block || "center" : "center";
198
+ document.querySelector(selector)?.scrollIntoView({
199
+ behavior,
200
+ block,
201
+ });
202
+ }
203
+ });
204
+
205
+ document.addEventListener("hxOpenURL", (event) => {
206
+ for (const { url, name, target, rel } of event.detail.value) {
207
+ const link = document.createElement("a");
208
+ link.href = url;
209
+ link.target = target || "_blank";
210
+ if (name) {
211
+ link.download = name;
212
+ }
213
+ if (rel) {
214
+ link.rel = rel;
215
+ }
216
+ link.click();
217
+ }
218
+ });
195
219
  })();
196
220
  // Local Variables:
197
221
  // js-indent-level: 4
djhtmx/testing.py CHANGED
@@ -13,7 +13,15 @@ from pygments.lexers import HtmlLexer
13
13
 
14
14
  from . import json
15
15
  from .commands import PushURL, ReplaceURL, SendHtml
16
- from .component import Destroy, DispatchDOMEvent, Focus, HtmxComponent, Open, Redirect
16
+ from .component import (
17
+ Destroy,
18
+ DispatchDOMEvent,
19
+ Focus,
20
+ HtmxComponent,
21
+ Open,
22
+ Redirect,
23
+ ScrollIntoView,
24
+ )
17
25
  from .introspection import parse_request_data
18
26
  from .repo import Repository, Session, signer
19
27
  from .utils import get_params
@@ -187,7 +195,7 @@ class Htmx:
187
195
  self.path = parsed_url.path
188
196
  self.query_string = parsed_url.query
189
197
 
190
- case Focus() | DispatchDOMEvent():
198
+ case Focus() | ScrollIntoView() | DispatchDOMEvent():
191
199
  pass
192
200
 
193
201
  if navigate_to_url:
djhtmx/urls.py CHANGED
@@ -11,7 +11,16 @@ from django.utils.html import format_html
11
11
  from django.views.decorators.csrf import csrf_exempt
12
12
 
13
13
  from .commands import PushURL, ReplaceURL, SendHtml
14
- from .component import REGISTRY, Destroy, DispatchDOMEvent, Focus, Open, Redirect, Triggers
14
+ from .component import (
15
+ REGISTRY,
16
+ Destroy,
17
+ DispatchDOMEvent,
18
+ Focus,
19
+ Open,
20
+ Redirect,
21
+ ScrollIntoView,
22
+ Triggers,
23
+ )
15
24
  from .consumer import Consumer
16
25
  from .introspection import parse_request_data
17
26
  from .repo import Repository
@@ -53,6 +62,11 @@ def endpoint(request: HttpRequest, component_name: str, component_id: str, event
53
62
  headers["HX-Redirect"] = url
54
63
  case Focus(selector):
55
64
  triggers.after_settle("hxFocus", selector)
65
+ case ScrollIntoView(selector, behavior, block):
66
+ triggers.after_settle(
67
+ "hxScrollIntoView",
68
+ {"selector": selector, "behavior": behavior, "block": block},
69
+ )
56
70
  case Open(url, name, target, rel):
57
71
  triggers.after_settle(
58
72
  "hxOpenURL",
djhtmx/utils.py CHANGED
@@ -1,5 +1,5 @@
1
- import contextlib
2
1
  import importlib
2
+ import logging
3
3
  import pkgutil
4
4
  import typing as t
5
5
  from urllib.parse import urlparse
@@ -129,17 +129,20 @@ def autodiscover_htmx_modules():
129
129
  - htmx.py files (like standard autodiscover_modules("htmx"))
130
130
  - All Python files under htmx/ directories in apps (recursively)
131
131
  """
132
-
133
- def _import_modules_recursively(module_name):
134
- """Recursively import a module and all its submodules."""
135
- with contextlib.suppress(ImportError):
136
- module = importlib.import_module(module_name)
137
-
138
- # If this is a package, recursively import all modules in it
139
- if hasattr(module, "__path__"):
140
- for _finder, submodule_name, _is_pkg in pkgutil.iter_modules(module.__path__):
141
- _import_modules_recursively(f"{module_name}.{submodule_name}")
142
-
143
132
  for app_config in apps.get_app_configs():
144
- # Import htmx module and all its submodules recursively
145
- _import_modules_recursively(f"{app_config.name}.htmx")
133
+ module_name = f"{app_config.module.__name__}.htmx"
134
+ try:
135
+ module = importlib.import_module(module_name)
136
+ except ImportError:
137
+ logger.warning("Could not import %s", module_name)
138
+ continue
139
+ if hasattr(module, "__path__"):
140
+ # If it's a package, recursively walk it importing all modules and packages.
141
+ for info in pkgutil.walk_packages(module.__path__, prefix=module_name + "."):
142
+ if not info.ispkg:
143
+ # `walk_packages` only imports packages, not modules; we need to import them
144
+ # all.
145
+ importlib.import_module(info.name)
146
+
147
+
148
+ logger = logging.getLogger(__name__)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: djhtmx
3
- Version: 1.2.8
3
+ Version: 1.2.9
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,9 +1,9 @@
1
- djhtmx/__init__.py,sha256=GkEUpRO-It4Hkf5iOG-R7kPFXr4QnXTPFkuj8Sx9KB0,84
1
+ djhtmx/__init__.py,sha256=Xo29y2KoMKHDn3Doa4sLhJWnPHI5uv_fhC_zm_8GBb4,84
2
2
  djhtmx/apps.py,sha256=hAyjzmInEstxLY9k8Qn58LvNlezgQLx5_NqyVL1WwYs,323
3
- djhtmx/command_queue.py,sha256=n1TERk9RmVT4dycmCroAOMLx_KXJ-HiqIA3qs_ptG7U,4884
3
+ djhtmx/command_queue.py,sha256=LSUkb2YMRt1lDyOg6WP7PoHsObynec0B55JyFtcshT0,5090
4
4
  djhtmx/commands.py,sha256=UxXbARd4Teetjh_zjvAWgI2KNbvdETH-WrGf4qD9Xr8,1206
5
- djhtmx/component.py,sha256=9Uhtdmpn4C6CbQYcMOwEoSHt4uPMx3VF22zEy2Gn9Y8,15988
6
- djhtmx/consumer.py,sha256=kHNoXokcWaFjs5zbZAhM7Y0x7GVwwawXbxBCkP8HNA8,2839
5
+ djhtmx/component.py,sha256=1aw5hAwq8MhQPP4cNCRQg9qO1GONd_KlxyYpcQeRhwg,16661
6
+ djhtmx/consumer.py,sha256=0Yh8urgMH3khA6_pWeY049w3jqHWZL_K9dErOhNctQA,2898
7
7
  djhtmx/context.py,sha256=cWvz8Z0MC6x_G8sn5mvoH8Hu38qReY21_eNdThuba1A,214
8
8
  djhtmx/exceptions.py,sha256=UtyE1N-52OmzwgRM9xFxjUuhHTMDvD7Oy3rNpgthLcs,47
9
9
  djhtmx/global_events.py,sha256=bYb8WmQn_WsZ_Dadr0pGiGOPia01K-VanPpM97Lt324,342
@@ -11,14 +11,14 @@ djhtmx/introspection.py,sha256=flVolO6xZiXsxMm876ZCEcWRmVfFsJWpAVmIdfcJNf8,13734
11
11
  djhtmx/json.py,sha256=7cjwWIJj7e0dk54INKYZJe6zKkIW7wlsNSlD05cbXfY,1374
12
12
  djhtmx/middleware.py,sha256=JuMtv9ZnpungTvQ1qD2Lg6LiFPB3knQlA1ERgH4iGl0,1274
13
13
  djhtmx/query.py,sha256=UyjN1jokh4wTwQJxcRwA9f-Zn-A7A4GLToeGrCnPhKA,6674
14
- djhtmx/repo.py,sha256=SpJK6KpxK9MraN29RvShaFt3ksifBAkv_gHUrxVkzIQ,22374
14
+ djhtmx/repo.py,sha256=Qw8t9i5_upfvYJyUr4Cb9hZoI9WUHhNOpszxjhtx9r4,22478
15
15
  djhtmx/settings.py,sha256=Iti4LkcKBTy-dNyCZxFH_cUp56aTcXjB5ftbssWyDnU,1318
16
- djhtmx/testing.py,sha256=AdZKsT6sNTsyqSKx6EmfthOIHzSAPkTquheMfg9znbk,8301
16
+ djhtmx/testing.py,sha256=QmZHrH6Up8uUxkVOHM6CyfocU774GL-lopJvM2X9Mkw,8369
17
17
  djhtmx/tracing.py,sha256=xkCXb7t_3yCj1PGzmQfHPu9sYQftDKwtALaEbFVnQ1E,1260
18
- djhtmx/urls.py,sha256=29BMD7fm05VFXtge3fRNDZuM5v_GziDm09n88aVp2fc,3961
19
- djhtmx/utils.py,sha256=BcCdJHe0AqkRT_Kj-XJT_sHCpOyXtumo9mQGN2WqHek,4646
18
+ djhtmx/urls.py,sha256=2LTzmBCd3lBlQcM6WrdQwkITxuL_4ArUHtiYbLk3T1M,4273
19
+ djhtmx/utils.py,sha256=LCRdBqdvFjXC5l6pywMq3fm344_KQwt3Y2MW2-Nw3tM,4711
20
20
  djhtmx/management/commands/htmx.py,sha256=tEtiJn_Z6byOFzBNIzTbdluA4T5q21zFwGvJ7yt90bw,3642
21
- djhtmx/static/htmx/django.js,sha256=XQgOfcqpF0Jtl9AZlrQ_tEBrNBdBj0OQ8hMFv3dLpoQ,6677
21
+ djhtmx/static/htmx/django.js,sha256=QDgkUBiX9PBa_bqfK2k4NwjBAgZlxYEK-JklOgn_IR4,5453
22
22
  djhtmx/static/htmx/2.0.4/htmx.amd.js,sha256=Hgmm_X5zw7ek0pjBaxhzH7OHx6Xfce5UYVa9ICWlWR0,165593
23
23
  djhtmx/static/htmx/2.0.4/htmx.cjs.js,sha256=4P3vh1eGwULBCT7wsKQ2bu4HiNQ_Kmnv2fP1RQ6_QW8,165586
24
24
  djhtmx/static/htmx/2.0.4/htmx.esm.d.ts,sha256=hV0FewMl4vWgZFCX_wIpSATGkXou7o1DXOLnVhvgvJI,7330
@@ -31,7 +31,7 @@ djhtmx/templates/htmx/headers.html,sha256=z7r9klwBDXDyjbHrzatZeHDvXB2DaZhgu55CFb
31
31
  djhtmx/templates/htmx/lazy.html,sha256=LfAThtKmFj-lCUZ7JWF_sC1Y6XsIpEz8A3IgWASn-J8,52
32
32
  djhtmx/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  djhtmx/templatetags/htmx.py,sha256=-qFqz4T9mCJocG9XIIey81cCYwk07XUd_DMpxNdmbsM,8397
34
- djhtmx-1.2.8.dist-info/METADATA,sha256=zQErUCYmXTb-42TMoDQkqZx6ss0FkkcrtVLAAvKeOOk,32245
35
- djhtmx-1.2.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
36
- djhtmx-1.2.8.dist-info/licenses/LICENSE,sha256=kCi_iSBUGsRZInQn96w7LXYzjiRjZ8FXl6vP--mFRPk,1085
37
- djhtmx-1.2.8.dist-info/RECORD,,
34
+ djhtmx-1.2.9.dist-info/METADATA,sha256=0JFyGGexxkpISm-AWnAlvzbQ0-Ga0RHGaCnmpWjT_XQ,32245
35
+ djhtmx-1.2.9.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
36
+ djhtmx-1.2.9.dist-info/licenses/LICENSE,sha256=kCi_iSBUGsRZInQn96w7LXYzjiRjZ8FXl6vP--mFRPk,1085
37
+ djhtmx-1.2.9.dist-info/RECORD,,
File without changes