htmx.org 2.0.0-alpha2 → 2.0.0-beta1

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.
package/README.md CHANGED
@@ -33,7 +33,7 @@ By removing these arbitrary constraints htmx completes HTML as a
33
33
  ## quick start
34
34
 
35
35
  ```html
36
- <script src="https://unpkg.com/htmx.org@1.9.10"></script>
36
+ <script src="https://unpkg.com/htmx.org@1.9.11"></script>
37
37
  <!-- have a button POST a click via AJAX -->
38
38
  <button hx-post="/clicked" hx-swap="outerHTML">
39
39
  Click Me
@@ -0,0 +1,9 @@
1
+ # Why Are These Files Here?
2
+
3
+ These are legacy extensions for htmx 1.x and are **NOT** actively maintained or guaranteed to work with htmx 2.x.
4
+ They are here because we unfortunately linked to unversioned unpkg URLs in the installation guides for them
5
+ in 1.x, so we need to keep them here to preserve those URLs and not break existing users functionality.
6
+
7
+ If you are looking for extensions for htmx 2.x, please see the [htmx 2.0 extensions site](https://extensions.htmx.org),
8
+ which has links to the new extensions repos (They have all been moved to their own NPM projects and URLs, like
9
+ they should have been from the start!)
@@ -0,0 +1,7 @@
1
+ htmx.defineExtension('ajax-header', {
2
+ onEvent: function (name, evt) {
3
+ if (name === "htmx:configRequest") {
4
+ evt.detail.headers['X-Requested-With'] = 'XMLHttpRequest';
5
+ }
6
+ }
7
+ });
@@ -0,0 +1,16 @@
1
+ htmx.defineExtension('alpine-morph', {
2
+ isInlineSwap: function (swapStyle) {
3
+ return swapStyle === 'morph';
4
+ },
5
+ handleSwap: function (swapStyle, target, fragment) {
6
+ if (swapStyle === 'morph') {
7
+ if (fragment.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
8
+ Alpine.morph(target, fragment.firstElementChild);
9
+ return [target];
10
+ } else {
11
+ Alpine.morph(target, fragment.outerHTML);
12
+ return [target];
13
+ }
14
+ }
15
+ }
16
+ });
@@ -0,0 +1,92 @@
1
+ (function () {
2
+
3
+ function splitOnWhitespace(trigger) {
4
+ return trigger.split(/\s+/);
5
+ }
6
+
7
+ function parseClassOperation(trimmedValue) {
8
+ var split = splitOnWhitespace(trimmedValue);
9
+ if (split.length > 1) {
10
+ var operation = split[0];
11
+ var classDef = split[1].trim();
12
+ var cssClass;
13
+ var delay;
14
+ if (classDef.indexOf(":") > 0) {
15
+ var splitCssClass = classDef.split(':');
16
+ cssClass = splitCssClass[0];
17
+ delay = htmx.parseInterval(splitCssClass[1]);
18
+ } else {
19
+ cssClass = classDef;
20
+ delay = 100;
21
+ }
22
+ return {
23
+ operation: operation,
24
+ cssClass: cssClass,
25
+ delay: delay
26
+ }
27
+ } else {
28
+ return null;
29
+ }
30
+ }
31
+
32
+ function performOperation(elt, classOperation, classList, currentRunTime) {
33
+ setTimeout(function () {
34
+ elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
35
+ }, currentRunTime)
36
+ }
37
+
38
+ function toggleOperation(elt, classOperation, classList, currentRunTime) {
39
+ setTimeout(function () {
40
+ setInterval(function () {
41
+ elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
42
+ }, classOperation.delay);
43
+ }, currentRunTime)
44
+ }
45
+
46
+ function processClassList(elt, classList) {
47
+ var runs = classList.split("&");
48
+ for (var i = 0; i < runs.length; i++) {
49
+ var run = runs[i];
50
+ var currentRunTime = 0;
51
+ var classOperations = run.split(",");
52
+ for (var j = 0; j < classOperations.length; j++) {
53
+ var value = classOperations[j];
54
+ var trimmedValue = value.trim();
55
+ var classOperation = parseClassOperation(trimmedValue);
56
+ if (classOperation) {
57
+ if (classOperation.operation === "toggle") {
58
+ toggleOperation(elt, classOperation, classList, currentRunTime);
59
+ currentRunTime = currentRunTime + classOperation.delay;
60
+ } else {
61
+ currentRunTime = currentRunTime + classOperation.delay;
62
+ performOperation(elt, classOperation, classList, currentRunTime);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ function maybeProcessClasses(elt) {
70
+ if (elt.getAttribute) {
71
+ var classList = elt.getAttribute("classes") || elt.getAttribute("data-classes");
72
+ if (classList) {
73
+ processClassList(elt, classList);
74
+ }
75
+ }
76
+ }
77
+
78
+ htmx.defineExtension('class-tools', {
79
+ onEvent: function (name, evt) {
80
+ if (name === "htmx:afterProcessNode") {
81
+ var elt = evt.detail.elt;
82
+ maybeProcessClasses(elt);
83
+ if (elt.querySelectorAll) {
84
+ var children = elt.querySelectorAll("[classes], [data-classes]");
85
+ for (var i = 0; i < children.length; i++) {
86
+ maybeProcessClasses(children[i]);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ });
92
+ })();
@@ -0,0 +1,96 @@
1
+ htmx.defineExtension('client-side-templates', {
2
+ transformResponse : function(text, xhr, elt) {
3
+
4
+ var mustacheTemplate = htmx.closest(elt, "[mustache-template]");
5
+ if (mustacheTemplate) {
6
+ var data = JSON.parse(text);
7
+ var templateId = mustacheTemplate.getAttribute('mustache-template');
8
+ var template = htmx.find("#" + templateId);
9
+ if (template) {
10
+ return Mustache.render(template.innerHTML, data);
11
+ } else {
12
+ throw "Unknown mustache template: " + templateId;
13
+ }
14
+ }
15
+
16
+ var mustacheArrayTemplate = htmx.closest(elt, "[mustache-array-template]");
17
+ if (mustacheArrayTemplate) {
18
+ var data = JSON.parse(text);
19
+ var templateId = mustacheArrayTemplate.getAttribute('mustache-array-template');
20
+ var template = htmx.find("#" + templateId);
21
+ if (template) {
22
+ return Mustache.render(template.innerHTML, {"data": data });
23
+ } else {
24
+ throw "Unknown mustache template: " + templateId;
25
+ }
26
+ }
27
+
28
+ var handlebarsTemplate = htmx.closest(elt, "[handlebars-template]");
29
+ if (handlebarsTemplate) {
30
+ var data = JSON.parse(text);
31
+ var templateId = handlebarsTemplate.getAttribute('handlebars-template');
32
+ var templateElement = htmx.find('#' + templateId).innerHTML;
33
+ var renderTemplate = Handlebars.compile(templateElement);
34
+ if (renderTemplate) {
35
+ return renderTemplate(data);
36
+ } else {
37
+ throw "Unknown handlebars template: " + templateId;
38
+ }
39
+ }
40
+
41
+ var handlebarsArrayTemplate = htmx.closest(elt, "[handlebars-array-template]");
42
+ if (handlebarsArrayTemplate) {
43
+ var data = JSON.parse(text);
44
+ var templateId = handlebarsArrayTemplate.getAttribute('handlebars-array-template');
45
+ var templateElement = htmx.find('#' + templateId).innerHTML;
46
+ var renderTemplate = Handlebars.compile(templateElement);
47
+ if (renderTemplate) {
48
+ return renderTemplate(data);
49
+ } else {
50
+ throw "Unknown handlebars template: " + templateId;
51
+ }
52
+ }
53
+
54
+ var nunjucksTemplate = htmx.closest(elt, "[nunjucks-template]");
55
+ if (nunjucksTemplate) {
56
+ var data = JSON.parse(text);
57
+ var templateName = nunjucksTemplate.getAttribute('nunjucks-template');
58
+ var template = htmx.find('#' + templateName);
59
+ if (template) {
60
+ return nunjucks.renderString(template.innerHTML, data);
61
+ } else {
62
+ return nunjucks.render(templateName, data);
63
+ }
64
+ }
65
+
66
+ var xsltTemplate = htmx.closest(elt, "[xslt-template]");
67
+ if (xsltTemplate) {
68
+ var templateId = xsltTemplate.getAttribute('xslt-template');
69
+ var template = htmx.find("#" + templateId);
70
+ if (template) {
71
+ var content = template.innerHTML ? new DOMParser().parseFromString(template.innerHTML, 'application/xml')
72
+ : template.contentDocument;
73
+ var processor = new XSLTProcessor();
74
+ processor.importStylesheet(content);
75
+ var data = new DOMParser().parseFromString(text, "application/xml");
76
+ var frag = processor.transformToFragment(data, document);
77
+ return new XMLSerializer().serializeToString(frag);
78
+ } else {
79
+ throw "Unknown XSLT template: " + templateId;
80
+ }
81
+ }
82
+
83
+ var nunjucksArrayTemplate = htmx.closest(elt, "[nunjucks-array-template]");
84
+ if (nunjucksArrayTemplate) {
85
+ var data = JSON.parse(text);
86
+ var templateName = nunjucksArrayTemplate.getAttribute('nunjucks-array-template');
87
+ var template = htmx.find('#' + templateName);
88
+ if (template) {
89
+ return nunjucks.renderString(template.innerHTML, {"data": data});
90
+ } else {
91
+ return nunjucks.render(templateName, {"data": data});
92
+ }
93
+ }
94
+ return text;
95
+ }
96
+ });
@@ -0,0 +1,11 @@
1
+ htmx.defineExtension('debug', {
2
+ onEvent: function (name, evt) {
3
+ if (console.debug) {
4
+ console.debug(name, evt);
5
+ } else if (console) {
6
+ console.log("DEBUG:", name, evt);
7
+ } else {
8
+ throw "NO CONSOLE SUPPORTED"
9
+ }
10
+ }
11
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ // Disable Submit Button
4
+ htmx.defineExtension('disable-element', {
5
+ onEvent: function (name, evt) {
6
+ let elt = evt.detail.elt;
7
+ let target = elt.getAttribute("hx-disable-element");
8
+ let targetElements = (target == "self") ? [ elt ] : document.querySelectorAll(target);
9
+
10
+ for (var i = 0; i < targetElements.length; i++) {
11
+ if (name === "htmx:beforeRequest" && targetElements[i]) {
12
+ targetElements[i].disabled = true;
13
+ } else if (name == "htmx:afterRequest" && targetElements[i]) {
14
+ targetElements[i].disabled = false;
15
+ }
16
+ }
17
+ }
18
+ });
@@ -0,0 +1,37 @@
1
+ (function(){
2
+ function stringifyEvent(event) {
3
+ var obj = {};
4
+ for (var key in event) {
5
+ obj[key] = event[key];
6
+ }
7
+ return JSON.stringify(obj, function(key, value){
8
+ if(value instanceof Node){
9
+ var nodeRep = value.tagName;
10
+ if (nodeRep) {
11
+ nodeRep = nodeRep.toLowerCase();
12
+ if(value.id){
13
+ nodeRep += "#" + value.id;
14
+ }
15
+ if(value.classList && value.classList.length){
16
+ nodeRep += "." + value.classList.toString().replace(" ", ".")
17
+ }
18
+ return nodeRep;
19
+ } else {
20
+ return "Node"
21
+ }
22
+ }
23
+ if (value instanceof Window) return 'Window';
24
+ return value;
25
+ });
26
+ }
27
+
28
+ htmx.defineExtension('event-header', {
29
+ onEvent: function (name, evt) {
30
+ if (name === "htmx:configRequest") {
31
+ if (evt.detail.triggeringEvent) {
32
+ evt.detail.headers['Triggering-Event'] = stringifyEvent(evt.detail.triggeringEvent);
33
+ }
34
+ }
35
+ }
36
+ });
37
+ })();
@@ -0,0 +1,141 @@
1
+ //==========================================================
2
+ // head-support.js
3
+ //
4
+ // An extension to htmx 1.0 to add head tag merging.
5
+ //==========================================================
6
+ (function(){
7
+
8
+ var api = null;
9
+
10
+ function log() {
11
+ //console.log(arguments);
12
+ }
13
+
14
+ function mergeHead(newContent, defaultMergeStrategy) {
15
+
16
+ if (newContent && newContent.indexOf('<head') > -1) {
17
+ const htmlDoc = document.createElement("html");
18
+ // remove svgs to avoid conflicts
19
+ var contentWithSvgsRemoved = newContent.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, '');
20
+ // extract head tag
21
+ var headTag = contentWithSvgsRemoved.match(/(<head(\s[^>]*>|>)([\s\S]*?)<\/head>)/im);
22
+
23
+ // if the head tag exists...
24
+ if (headTag) {
25
+
26
+ var added = []
27
+ var removed = []
28
+ var preserved = []
29
+ var nodesToAppend = []
30
+
31
+ htmlDoc.innerHTML = headTag;
32
+ var newHeadTag = htmlDoc.querySelector("head");
33
+ var currentHead = document.head;
34
+
35
+ if (newHeadTag == null) {
36
+ return;
37
+ } else {
38
+ // put all new head elements into a Map, by their outerHTML
39
+ var srcToNewHeadNodes = new Map();
40
+ for (const newHeadChild of newHeadTag.children) {
41
+ srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);
42
+ }
43
+ }
44
+
45
+
46
+
47
+ // determine merge strategy
48
+ var mergeStrategy = api.getAttributeValue(newHeadTag, "hx-head") || defaultMergeStrategy;
49
+
50
+ // get the current head
51
+ for (const currentHeadElt of currentHead.children) {
52
+
53
+ // If the current head element is in the map
54
+ var inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);
55
+ var isReAppended = currentHeadElt.getAttribute("hx-head") === "re-eval";
56
+ var isPreserved = api.getAttributeValue(currentHeadElt, "hx-preserve") === "true";
57
+ if (inNewContent || isPreserved) {
58
+ if (isReAppended) {
59
+ // remove the current version and let the new version replace it and re-execute
60
+ removed.push(currentHeadElt);
61
+ } else {
62
+ // this element already exists and should not be re-appended, so remove it from
63
+ // the new content map, preserving it in the DOM
64
+ srcToNewHeadNodes.delete(currentHeadElt.outerHTML);
65
+ preserved.push(currentHeadElt);
66
+ }
67
+ } else {
68
+ if (mergeStrategy === "append") {
69
+ // we are appending and this existing element is not new content
70
+ // so if and only if it is marked for re-append do we do anything
71
+ if (isReAppended) {
72
+ removed.push(currentHeadElt);
73
+ nodesToAppend.push(currentHeadElt);
74
+ }
75
+ } else {
76
+ // if this is a merge, we remove this content since it is not in the new head
77
+ if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: currentHeadElt}) !== false) {
78
+ removed.push(currentHeadElt);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ // Push the tremaining new head elements in the Map into the
85
+ // nodes to append to the head tag
86
+ nodesToAppend.push(...srcToNewHeadNodes.values());
87
+ log("to append: ", nodesToAppend);
88
+
89
+ for (const newNode of nodesToAppend) {
90
+ log("adding: ", newNode);
91
+ var newElt = document.createRange().createContextualFragment(newNode.outerHTML);
92
+ log(newElt);
93
+ if (api.triggerEvent(document.body, "htmx:addingHeadElement", {headElement: newElt}) !== false) {
94
+ currentHead.appendChild(newElt);
95
+ added.push(newElt);
96
+ }
97
+ }
98
+
99
+ // remove all removed elements, after we have appended the new elements to avoid
100
+ // additional network requests for things like style sheets
101
+ for (const removedElement of removed) {
102
+ if (api.triggerEvent(document.body, "htmx:removingHeadElement", {headElement: removedElement}) !== false) {
103
+ currentHead.removeChild(removedElement);
104
+ }
105
+ }
106
+
107
+ api.triggerEvent(document.body, "htmx:afterHeadMerge", {added: added, kept: preserved, removed: removed});
108
+ }
109
+ }
110
+ }
111
+
112
+ htmx.defineExtension("head-support", {
113
+ init: function(apiRef) {
114
+ // store a reference to the internal API.
115
+ api = apiRef;
116
+
117
+ htmx.on('htmx:afterSwap', function(evt){
118
+ var serverResponse = evt.detail.xhr.response;
119
+ if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) {
120
+ mergeHead(serverResponse, evt.detail.boosted ? "merge" : "append");
121
+ }
122
+ })
123
+
124
+ htmx.on('htmx:historyRestore', function(evt){
125
+ if (api.triggerEvent(document.body, "htmx:beforeHeadMerge", evt.detail)) {
126
+ if (evt.detail.cacheMiss) {
127
+ mergeHead(evt.detail.serverResponse, "merge");
128
+ } else {
129
+ mergeHead(evt.detail.item.head, "merge");
130
+ }
131
+ }
132
+ })
133
+
134
+ htmx.on('htmx:historyItemCreated', function(evt){
135
+ var historyItem = evt.detail.item;
136
+ historyItem.head = document.head.outerHTML;
137
+ })
138
+ }
139
+ });
140
+
141
+ })()
@@ -0,0 +1,24 @@
1
+ (function(){
2
+
3
+ function mergeObjects(obj1, obj2) {
4
+ for (var key in obj2) {
5
+ if (obj2.hasOwnProperty(key)) {
6
+ obj1[key] = obj2[key];
7
+ }
8
+ }
9
+ return obj1;
10
+ }
11
+
12
+ htmx.defineExtension('include-vals', {
13
+ onEvent: function (name, evt) {
14
+ if (name === "htmx:configRequest") {
15
+ var includeValsElt = htmx.closest(evt.detail.elt, "[include-vals],[data-include-vals]");
16
+ if (includeValsElt) {
17
+ var includeVals = includeValsElt.getAttribute("include-vals") || includeValsElt.getAttribute("data-include-vals");
18
+ var valuesToInclude = eval("({" + includeVals + "})");
19
+ mergeObjects(evt.detail.parameters, valuesToInclude);
20
+ }
21
+ }
22
+ }
23
+ });
24
+ })();
@@ -0,0 +1,12 @@
1
+ htmx.defineExtension('json-enc', {
2
+ onEvent: function (name, evt) {
3
+ if (name === "htmx:configRequest") {
4
+ evt.detail.headers['Content-Type'] = "application/json";
5
+ }
6
+ },
7
+
8
+ encodeParameters : function(xhr, parameters, elt) {
9
+ xhr.overrideMimeType('text/json');
10
+ return (JSON.stringify(parameters));
11
+ }
12
+ });
@@ -0,0 +1,183 @@
1
+ ;(function () {
2
+ let loadingStatesUndoQueue = []
3
+
4
+ function loadingStateContainer(target) {
5
+ return htmx.closest(target, '[data-loading-states]') || document.body
6
+ }
7
+
8
+ function mayProcessUndoCallback(target, callback) {
9
+ if (document.body.contains(target)) {
10
+ callback()
11
+ }
12
+ }
13
+
14
+ function mayProcessLoadingStateByPath(elt, requestPath) {
15
+ const pathElt = htmx.closest(elt, '[data-loading-path]')
16
+ if (!pathElt) {
17
+ return true
18
+ }
19
+
20
+ return pathElt.getAttribute('data-loading-path') === requestPath
21
+ }
22
+
23
+ function queueLoadingState(sourceElt, targetElt, doCallback, undoCallback) {
24
+ const delayElt = htmx.closest(sourceElt, '[data-loading-delay]')
25
+ if (delayElt) {
26
+ const delayInMilliseconds =
27
+ delayElt.getAttribute('data-loading-delay') || 200
28
+ const timeout = setTimeout(function () {
29
+ doCallback()
30
+
31
+ loadingStatesUndoQueue.push(function () {
32
+ mayProcessUndoCallback(targetElt, undoCallback)
33
+ })
34
+ }, delayInMilliseconds)
35
+
36
+ loadingStatesUndoQueue.push(function () {
37
+ mayProcessUndoCallback(targetElt, function () { clearTimeout(timeout) })
38
+ })
39
+ } else {
40
+ doCallback()
41
+ loadingStatesUndoQueue.push(function () {
42
+ mayProcessUndoCallback(targetElt, undoCallback)
43
+ })
44
+ }
45
+ }
46
+
47
+ function getLoadingStateElts(loadingScope, type, path) {
48
+ return Array.from(htmx.findAll(loadingScope, "[" + type + "]")).filter(
49
+ function (elt) { return mayProcessLoadingStateByPath(elt, path) }
50
+ )
51
+ }
52
+
53
+ function getLoadingTarget(elt) {
54
+ if (elt.getAttribute('data-loading-target')) {
55
+ return Array.from(
56
+ htmx.findAll(elt.getAttribute('data-loading-target'))
57
+ )
58
+ }
59
+ return [elt]
60
+ }
61
+
62
+ htmx.defineExtension('loading-states', {
63
+ onEvent: function (name, evt) {
64
+ if (name === 'htmx:beforeRequest') {
65
+ const container = loadingStateContainer(evt.target)
66
+
67
+ const loadingStateTypes = [
68
+ 'data-loading',
69
+ 'data-loading-class',
70
+ 'data-loading-class-remove',
71
+ 'data-loading-disable',
72
+ 'data-loading-aria-busy',
73
+ ]
74
+
75
+ let loadingStateEltsByType = {}
76
+
77
+ loadingStateTypes.forEach(function (type) {
78
+ loadingStateEltsByType[type] = getLoadingStateElts(
79
+ container,
80
+ type,
81
+ evt.detail.pathInfo.requestPath
82
+ )
83
+ })
84
+
85
+ loadingStateEltsByType['data-loading'].forEach(function (sourceElt) {
86
+ getLoadingTarget(sourceElt).forEach(function (targetElt) {
87
+ queueLoadingState(
88
+ sourceElt,
89
+ targetElt,
90
+ function () {
91
+ targetElt.style.display =
92
+ sourceElt.getAttribute('data-loading') ||
93
+ 'inline-block' },
94
+ function () { targetElt.style.display = 'none' }
95
+ )
96
+ })
97
+ })
98
+
99
+ loadingStateEltsByType['data-loading-class'].forEach(
100
+ function (sourceElt) {
101
+ const classNames = sourceElt
102
+ .getAttribute('data-loading-class')
103
+ .split(' ')
104
+
105
+ getLoadingTarget(sourceElt).forEach(function (targetElt) {
106
+ queueLoadingState(
107
+ sourceElt,
108
+ targetElt,
109
+ function () {
110
+ classNames.forEach(function (className) {
111
+ targetElt.classList.add(className)
112
+ })
113
+ },
114
+ function() {
115
+ classNames.forEach(function (className) {
116
+ targetElt.classList.remove(className)
117
+ })
118
+ }
119
+ )
120
+ })
121
+ }
122
+ )
123
+
124
+ loadingStateEltsByType['data-loading-class-remove'].forEach(
125
+ function (sourceElt) {
126
+ const classNames = sourceElt
127
+ .getAttribute('data-loading-class-remove')
128
+ .split(' ')
129
+
130
+ getLoadingTarget(sourceElt).forEach(function (targetElt) {
131
+ queueLoadingState(
132
+ sourceElt,
133
+ targetElt,
134
+ function () {
135
+ classNames.forEach(function (className) {
136
+ targetElt.classList.remove(className)
137
+ })
138
+ },
139
+ function() {
140
+ classNames.forEach(function (className) {
141
+ targetElt.classList.add(className)
142
+ })
143
+ }
144
+ )
145
+ })
146
+ }
147
+ )
148
+
149
+ loadingStateEltsByType['data-loading-disable'].forEach(
150
+ function (sourceElt) {
151
+ getLoadingTarget(sourceElt).forEach(function (targetElt) {
152
+ queueLoadingState(
153
+ sourceElt,
154
+ targetElt,
155
+ function() { targetElt.disabled = true },
156
+ function() { targetElt.disabled = false }
157
+ )
158
+ })
159
+ }
160
+ )
161
+
162
+ loadingStateEltsByType['data-loading-aria-busy'].forEach(
163
+ function (sourceElt) {
164
+ getLoadingTarget(sourceElt).forEach(function (targetElt) {
165
+ queueLoadingState(
166
+ sourceElt,
167
+ targetElt,
168
+ function () { targetElt.setAttribute("aria-busy", "true") },
169
+ function () { targetElt.removeAttribute("aria-busy") }
170
+ )
171
+ })
172
+ }
173
+ )
174
+ }
175
+
176
+ if (name === 'htmx:beforeOnLoad') {
177
+ while (loadingStatesUndoQueue.length > 0) {
178
+ loadingStatesUndoQueue.shift()()
179
+ }
180
+ }
181
+ },
182
+ })
183
+ })()
@@ -0,0 +1,11 @@
1
+ htmx.defineExtension('method-override', {
2
+ onEvent: function (name, evt) {
3
+ if (name === "htmx:configRequest") {
4
+ var method = evt.detail.verb;
5
+ if (method !== "get" || method !== "post") {
6
+ evt.detail.headers['X-HTTP-Method-Override'] = method.toUpperCase();
7
+ evt.detail.verb = "post";
8
+ }
9
+ }
10
+ }
11
+ });