htmx.org 1.9.9 → 1.9.11
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/LICENSE +13 -25
- package/README.md +1 -1
- package/dist/ext/path-params.js +11 -0
- package/dist/ext/sse.js +136 -89
- package/dist/ext/ws.js +2 -3
- package/dist/htmx.d.ts +75 -2
- package/dist/htmx.js +245 -178
- package/dist/htmx.min.js +1 -1
- package/dist/htmx.min.js.gz +0 -0
- package/package.json +2 -2
- package/CHANGELOG.md +0 -466
package/dist/htmx.js
CHANGED
|
@@ -76,7 +76,8 @@ return (function () {
|
|
|
76
76
|
methodsThatUseUrlParams: ["get"],
|
|
77
77
|
selfRequestsOnly: false,
|
|
78
78
|
ignoreTitle: false,
|
|
79
|
-
scrollIntoViewOnBoost: true
|
|
79
|
+
scrollIntoViewOnBoost: true,
|
|
80
|
+
triggerSpecsCache: null,
|
|
80
81
|
},
|
|
81
82
|
parseInterval:parseInterval,
|
|
82
83
|
_:internalEval,
|
|
@@ -88,7 +89,7 @@ return (function () {
|
|
|
88
89
|
sock.binaryType = htmx.config.wsBinaryType;
|
|
89
90
|
return sock;
|
|
90
91
|
},
|
|
91
|
-
version: "1.9.
|
|
92
|
+
version: "1.9.11"
|
|
92
93
|
};
|
|
93
94
|
|
|
94
95
|
/** @type {import("./htmx").HtmxInternalApi} */
|
|
@@ -127,24 +128,40 @@ return (function () {
|
|
|
127
128
|
return "[hx-" + verb + "], [data-hx-" + verb + "]"
|
|
128
129
|
}).join(", ");
|
|
129
130
|
|
|
131
|
+
var HEAD_TAG_REGEX = makeTagRegEx('head'),
|
|
132
|
+
TITLE_TAG_REGEX = makeTagRegEx('title'),
|
|
133
|
+
SVG_TAGS_REGEX = makeTagRegEx('svg', true);
|
|
134
|
+
|
|
130
135
|
//====================================================================
|
|
131
136
|
// Utilities
|
|
132
137
|
//====================================================================
|
|
133
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @param {string} tag
|
|
141
|
+
* @param {boolean} global
|
|
142
|
+
* @returns {RegExp}
|
|
143
|
+
*/
|
|
144
|
+
function makeTagRegEx(tag, global = false) {
|
|
145
|
+
return new RegExp(`<${tag}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${tag}>`,
|
|
146
|
+
global ? 'gim' : 'im');
|
|
147
|
+
}
|
|
148
|
+
|
|
134
149
|
function parseInterval(str) {
|
|
135
150
|
if (str == undefined) {
|
|
136
|
-
return undefined
|
|
151
|
+
return undefined;
|
|
137
152
|
}
|
|
153
|
+
|
|
154
|
+
let interval = NaN;
|
|
138
155
|
if (str.slice(-2) == "ms") {
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
156
|
+
interval = parseFloat(str.slice(0, -2));
|
|
157
|
+
} else if (str.slice(-1) == "s") {
|
|
158
|
+
interval = parseFloat(str.slice(0, -1)) * 1000;
|
|
159
|
+
} else if (str.slice(-1) == "m") {
|
|
160
|
+
interval = parseFloat(str.slice(0, -1)) * 1000 * 60;
|
|
161
|
+
} else {
|
|
162
|
+
interval = parseFloat(str);
|
|
146
163
|
}
|
|
147
|
-
return
|
|
164
|
+
return isNaN(interval) ? undefined : interval;
|
|
148
165
|
}
|
|
149
166
|
|
|
150
167
|
/**
|
|
@@ -276,43 +293,62 @@ return (function () {
|
|
|
276
293
|
}
|
|
277
294
|
|
|
278
295
|
function aFullPageResponse(resp) {
|
|
279
|
-
return
|
|
296
|
+
return /<body/.test(resp)
|
|
280
297
|
}
|
|
281
298
|
|
|
282
299
|
/**
|
|
283
300
|
*
|
|
284
|
-
* @param {string}
|
|
301
|
+
* @param {string} response
|
|
285
302
|
* @returns {Element}
|
|
286
303
|
*/
|
|
287
|
-
function makeFragment(
|
|
288
|
-
var partialResponse = !aFullPageResponse(
|
|
304
|
+
function makeFragment(response) {
|
|
305
|
+
var partialResponse = !aFullPageResponse(response);
|
|
306
|
+
var startTag = getStartTag(response);
|
|
307
|
+
var content = response;
|
|
308
|
+
if (startTag === 'head') {
|
|
309
|
+
content = content.replace(HEAD_TAG_REGEX, '');
|
|
310
|
+
}
|
|
289
311
|
if (htmx.config.useTemplateFragments && partialResponse) {
|
|
290
|
-
var
|
|
312
|
+
var fragment = parseHTML("<body><template>" + content + "</template></body>", 0);
|
|
291
313
|
// @ts-ignore type mismatch between DocumentFragment and Element.
|
|
292
314
|
// TODO: Are these close enough for htmx to use interchangeably?
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
case "th":
|
|
309
|
-
return parseHTML("<table><tbody><tr>" + resp + "</tr></tbody></table>", 3);
|
|
310
|
-
case "script":
|
|
311
|
-
case "style":
|
|
312
|
-
return parseHTML("<div>" + resp + "</div>", 1);
|
|
313
|
-
default:
|
|
314
|
-
return parseHTML(resp, 0);
|
|
315
|
+
var fragmentContent = fragment.querySelector('template').content;
|
|
316
|
+
if (htmx.config.allowScriptTags) {
|
|
317
|
+
// if there is a nonce set up, set it on the new script tags
|
|
318
|
+
forEach(fragmentContent.querySelectorAll("script"), function (script) {
|
|
319
|
+
if (htmx.config.inlineScriptNonce) {
|
|
320
|
+
script.nonce = htmx.config.inlineScriptNonce;
|
|
321
|
+
}
|
|
322
|
+
// mark as executed due to template insertion semantics on all browsers except firefox fml
|
|
323
|
+
script.htmxExecuted = navigator.userAgent.indexOf("Firefox") === -1;
|
|
324
|
+
})
|
|
325
|
+
} else {
|
|
326
|
+
forEach(fragmentContent.querySelectorAll("script"), function (script) {
|
|
327
|
+
// remove all script tags if scripts are disabled
|
|
328
|
+
removeElement(script);
|
|
329
|
+
})
|
|
315
330
|
}
|
|
331
|
+
return fragmentContent;
|
|
332
|
+
}
|
|
333
|
+
switch (startTag) {
|
|
334
|
+
case "thead":
|
|
335
|
+
case "tbody":
|
|
336
|
+
case "tfoot":
|
|
337
|
+
case "colgroup":
|
|
338
|
+
case "caption":
|
|
339
|
+
return parseHTML("<table>" + content + "</table>", 1);
|
|
340
|
+
case "col":
|
|
341
|
+
return parseHTML("<table><colgroup>" + content + "</colgroup></table>", 2);
|
|
342
|
+
case "tr":
|
|
343
|
+
return parseHTML("<table><tbody>" + content + "</tbody></table>", 2);
|
|
344
|
+
case "td":
|
|
345
|
+
case "th":
|
|
346
|
+
return parseHTML("<table><tbody><tr>" + content + "</tr></tbody></table>", 3);
|
|
347
|
+
case "script":
|
|
348
|
+
case "style":
|
|
349
|
+
return parseHTML("<div>" + content + "</div>", 1);
|
|
350
|
+
default:
|
|
351
|
+
return parseHTML(content, 0);
|
|
316
352
|
}
|
|
317
353
|
}
|
|
318
354
|
|
|
@@ -450,7 +486,7 @@ return (function () {
|
|
|
450
486
|
path = url.pathname + url.search;
|
|
451
487
|
}
|
|
452
488
|
// remove trailing slash, unless index page
|
|
453
|
-
if (!path
|
|
489
|
+
if (!(/^\/$/.test(path))) {
|
|
454
490
|
path = path.replace(/\/+$/, '');
|
|
455
491
|
}
|
|
456
492
|
return path;
|
|
@@ -827,7 +863,7 @@ return (function () {
|
|
|
827
863
|
var oobSelects = getClosestAttributeValue(elt, "hx-select-oob");
|
|
828
864
|
if (oobSelects) {
|
|
829
865
|
var oobSelectValues = oobSelects.split(",");
|
|
830
|
-
for (
|
|
866
|
+
for (var i = 0; i < oobSelectValues.length; i++) {
|
|
831
867
|
var oobSelectValue = oobSelectValues[i].split(":", 2);
|
|
832
868
|
var id = oobSelectValue[0].trim();
|
|
833
869
|
if (id.indexOf("#") === 0) {
|
|
@@ -934,7 +970,7 @@ return (function () {
|
|
|
934
970
|
function deInitOnHandlers(elt) {
|
|
935
971
|
var internalData = getInternalData(elt);
|
|
936
972
|
if (internalData.onHandlers) {
|
|
937
|
-
for (
|
|
973
|
+
for (var i = 0; i < internalData.onHandlers.length; i++) {
|
|
938
974
|
const handlerInfo = internalData.onHandlers[i];
|
|
939
975
|
elt.removeEventListener(handlerInfo.event, handlerInfo.listener);
|
|
940
976
|
}
|
|
@@ -960,10 +996,8 @@ return (function () {
|
|
|
960
996
|
}
|
|
961
997
|
});
|
|
962
998
|
}
|
|
963
|
-
if (internalData.initHash) {
|
|
964
|
-
internalData.initHash = null
|
|
965
|
-
}
|
|
966
999
|
deInitOnHandlers(element);
|
|
1000
|
+
forEach(Object.keys(internalData), function(key) { delete internalData[key] });
|
|
967
1001
|
}
|
|
968
1002
|
|
|
969
1003
|
function cleanUpElement(element) {
|
|
@@ -987,7 +1021,6 @@ return (function () {
|
|
|
987
1021
|
} else {
|
|
988
1022
|
newElt = eltBeforeNewContent.nextSibling;
|
|
989
1023
|
}
|
|
990
|
-
getInternalData(target).replacedWith = newElt; // tuck away so we can fire events on it later
|
|
991
1024
|
settleInfo.elts = settleInfo.elts.filter(function(e) { return e != target });
|
|
992
1025
|
while(newElt && newElt !== target) {
|
|
993
1026
|
if (newElt.nodeType === Node.ELEMENT_NODE) {
|
|
@@ -1099,9 +1132,8 @@ return (function () {
|
|
|
1099
1132
|
|
|
1100
1133
|
function findTitle(content) {
|
|
1101
1134
|
if (content.indexOf('<title') > -1) {
|
|
1102
|
-
var contentWithSvgsRemoved = content.replace(
|
|
1103
|
-
var result = contentWithSvgsRemoved.match(
|
|
1104
|
-
|
|
1135
|
+
var contentWithSvgsRemoved = content.replace(SVG_TAGS_REGEX, '');
|
|
1136
|
+
var result = contentWithSvgsRemoved.match(TITLE_TAG_REGEX);
|
|
1105
1137
|
if (result) {
|
|
1106
1138
|
return result[2];
|
|
1107
1139
|
}
|
|
@@ -1230,7 +1262,7 @@ return (function () {
|
|
|
1230
1262
|
|
|
1231
1263
|
function consumeUntil(tokens, match) {
|
|
1232
1264
|
var result = "";
|
|
1233
|
-
while (tokens.length > 0 && !tokens[0]
|
|
1265
|
+
while (tokens.length > 0 && !match.test(tokens[0])) {
|
|
1234
1266
|
result += tokens.shift();
|
|
1235
1267
|
}
|
|
1236
1268
|
return result;
|
|
@@ -1252,91 +1284,107 @@ return (function () {
|
|
|
1252
1284
|
|
|
1253
1285
|
/**
|
|
1254
1286
|
* @param {HTMLElement} elt
|
|
1287
|
+
* @param {string} explicitTrigger
|
|
1288
|
+
* @param {cache} cache for trigger specs
|
|
1255
1289
|
* @returns {import("./htmx").HtmxTriggerSpecification[]}
|
|
1256
1290
|
*/
|
|
1257
|
-
function
|
|
1258
|
-
var explicitTrigger = getAttributeValue(elt, 'hx-trigger');
|
|
1291
|
+
function parseAndCacheTrigger(elt, explicitTrigger, cache) {
|
|
1259
1292
|
var triggerSpecs = [];
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
if (trigger
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
from_arg += " " + selector;
|
|
1309
|
-
}
|
|
1293
|
+
var tokens = tokenizeString(explicitTrigger);
|
|
1294
|
+
do {
|
|
1295
|
+
consumeUntil(tokens, NOT_WHITESPACE);
|
|
1296
|
+
var initialLength = tokens.length;
|
|
1297
|
+
var trigger = consumeUntil(tokens, /[,\[\s]/);
|
|
1298
|
+
if (trigger !== "") {
|
|
1299
|
+
if (trigger === "every") {
|
|
1300
|
+
var every = {trigger: 'every'};
|
|
1301
|
+
consumeUntil(tokens, NOT_WHITESPACE);
|
|
1302
|
+
every.pollInterval = parseInterval(consumeUntil(tokens, /[,\[\s]/));
|
|
1303
|
+
consumeUntil(tokens, NOT_WHITESPACE);
|
|
1304
|
+
var eventFilter = maybeGenerateConditional(elt, tokens, "event");
|
|
1305
|
+
if (eventFilter) {
|
|
1306
|
+
every.eventFilter = eventFilter;
|
|
1307
|
+
}
|
|
1308
|
+
triggerSpecs.push(every);
|
|
1309
|
+
} else if (trigger.indexOf("sse:") === 0) {
|
|
1310
|
+
triggerSpecs.push({trigger: 'sse', sseEvent: trigger.substr(4)});
|
|
1311
|
+
} else {
|
|
1312
|
+
var triggerSpec = {trigger: trigger};
|
|
1313
|
+
var eventFilter = maybeGenerateConditional(elt, tokens, "event");
|
|
1314
|
+
if (eventFilter) {
|
|
1315
|
+
triggerSpec.eventFilter = eventFilter;
|
|
1316
|
+
}
|
|
1317
|
+
while (tokens.length > 0 && tokens[0] !== ",") {
|
|
1318
|
+
consumeUntil(tokens, NOT_WHITESPACE)
|
|
1319
|
+
var token = tokens.shift();
|
|
1320
|
+
if (token === "changed") {
|
|
1321
|
+
triggerSpec.changed = true;
|
|
1322
|
+
} else if (token === "once") {
|
|
1323
|
+
triggerSpec.once = true;
|
|
1324
|
+
} else if (token === "consume") {
|
|
1325
|
+
triggerSpec.consume = true;
|
|
1326
|
+
} else if (token === "delay" && tokens[0] === ":") {
|
|
1327
|
+
tokens.shift();
|
|
1328
|
+
triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA));
|
|
1329
|
+
} else if (token === "from" && tokens[0] === ":") {
|
|
1330
|
+
tokens.shift();
|
|
1331
|
+
if (COMBINED_SELECTOR_START.test(tokens[0])) {
|
|
1332
|
+
var from_arg = consumeCSSSelector(tokens);
|
|
1333
|
+
} else {
|
|
1334
|
+
var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
|
1335
|
+
if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") {
|
|
1336
|
+
tokens.shift();
|
|
1337
|
+
var selector = consumeCSSSelector(tokens);
|
|
1338
|
+
// `next` and `previous` allow a selector-less syntax
|
|
1339
|
+
if (selector.length > 0) {
|
|
1340
|
+
from_arg += " " + selector;
|
|
1310
1341
|
}
|
|
1311
1342
|
}
|
|
1312
|
-
triggerSpec.from = from_arg;
|
|
1313
|
-
} else if (token === "target" && tokens[0] === ":") {
|
|
1314
|
-
tokens.shift();
|
|
1315
|
-
triggerSpec.target = consumeCSSSelector(tokens);
|
|
1316
|
-
} else if (token === "throttle" && tokens[0] === ":") {
|
|
1317
|
-
tokens.shift();
|
|
1318
|
-
triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA));
|
|
1319
|
-
} else if (token === "queue" && tokens[0] === ":") {
|
|
1320
|
-
tokens.shift();
|
|
1321
|
-
triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
|
1322
|
-
} else if (token === "root" && tokens[0] === ":") {
|
|
1323
|
-
tokens.shift();
|
|
1324
|
-
triggerSpec[token] = consumeCSSSelector(tokens);
|
|
1325
|
-
} else if (token === "threshold" && tokens[0] === ":") {
|
|
1326
|
-
tokens.shift();
|
|
1327
|
-
triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
|
1328
|
-
} else {
|
|
1329
|
-
triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()});
|
|
1330
1343
|
}
|
|
1344
|
+
triggerSpec.from = from_arg;
|
|
1345
|
+
} else if (token === "target" && tokens[0] === ":") {
|
|
1346
|
+
tokens.shift();
|
|
1347
|
+
triggerSpec.target = consumeCSSSelector(tokens);
|
|
1348
|
+
} else if (token === "throttle" && tokens[0] === ":") {
|
|
1349
|
+
tokens.shift();
|
|
1350
|
+
triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA));
|
|
1351
|
+
} else if (token === "queue" && tokens[0] === ":") {
|
|
1352
|
+
tokens.shift();
|
|
1353
|
+
triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
|
1354
|
+
} else if (token === "root" && tokens[0] === ":") {
|
|
1355
|
+
tokens.shift();
|
|
1356
|
+
triggerSpec[token] = consumeCSSSelector(tokens);
|
|
1357
|
+
} else if (token === "threshold" && tokens[0] === ":") {
|
|
1358
|
+
tokens.shift();
|
|
1359
|
+
triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA);
|
|
1360
|
+
} else {
|
|
1361
|
+
triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()});
|
|
1331
1362
|
}
|
|
1332
|
-
triggerSpecs.push(triggerSpec);
|
|
1333
1363
|
}
|
|
1364
|
+
triggerSpecs.push(triggerSpec);
|
|
1334
1365
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1366
|
+
}
|
|
1367
|
+
if (tokens.length === initialLength) {
|
|
1368
|
+
triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()});
|
|
1369
|
+
}
|
|
1370
|
+
consumeUntil(tokens, NOT_WHITESPACE);
|
|
1371
|
+
} while (tokens[0] === "," && tokens.shift())
|
|
1372
|
+
if (cache) {
|
|
1373
|
+
cache[explicitTrigger] = triggerSpecs
|
|
1374
|
+
}
|
|
1375
|
+
return triggerSpecs
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* @param {HTMLElement} elt
|
|
1380
|
+
* @returns {import("./htmx").HtmxTriggerSpecification[]}
|
|
1381
|
+
*/
|
|
1382
|
+
function getTriggerSpecs(elt) {
|
|
1383
|
+
var explicitTrigger = getAttributeValue(elt, 'hx-trigger');
|
|
1384
|
+
var triggerSpecs = [];
|
|
1385
|
+
if (explicitTrigger) {
|
|
1386
|
+
var cache = htmx.config.triggerSpecsCache
|
|
1387
|
+
triggerSpecs = (cache && cache[explicitTrigger]) || parseAndCacheTrigger(elt, explicitTrigger, cache)
|
|
1340
1388
|
}
|
|
1341
1389
|
|
|
1342
1390
|
if (triggerSpecs.length > 0) {
|
|
@@ -1508,14 +1556,14 @@ return (function () {
|
|
|
1508
1556
|
return;
|
|
1509
1557
|
}
|
|
1510
1558
|
|
|
1511
|
-
if (triggerSpec.throttle) {
|
|
1559
|
+
if (triggerSpec.throttle > 0) {
|
|
1512
1560
|
if (!elementData.throttle) {
|
|
1513
1561
|
handler(elt, evt);
|
|
1514
1562
|
elementData.throttle = setTimeout(function () {
|
|
1515
1563
|
elementData.throttle = null;
|
|
1516
1564
|
}, triggerSpec.throttle);
|
|
1517
1565
|
}
|
|
1518
|
-
} else if (triggerSpec.delay) {
|
|
1566
|
+
} else if (triggerSpec.delay > 0) {
|
|
1519
1567
|
elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay);
|
|
1520
1568
|
} else {
|
|
1521
1569
|
triggerEvent(elt, 'htmx:trigger')
|
|
@@ -1792,7 +1840,7 @@ return (function () {
|
|
|
1792
1840
|
handler(elt);
|
|
1793
1841
|
}
|
|
1794
1842
|
}
|
|
1795
|
-
if (delay) {
|
|
1843
|
+
if (delay > 0) {
|
|
1796
1844
|
setTimeout(load, delay);
|
|
1797
1845
|
} else {
|
|
1798
1846
|
load();
|
|
@@ -1851,7 +1899,7 @@ return (function () {
|
|
|
1851
1899
|
if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", {elt: elt}))) {
|
|
1852
1900
|
loadImmediately(elt, handler, nodeData, triggerSpec.delay);
|
|
1853
1901
|
}
|
|
1854
|
-
} else if (triggerSpec.pollInterval) {
|
|
1902
|
+
} else if (triggerSpec.pollInterval > 0) {
|
|
1855
1903
|
nodeData.polling = true;
|
|
1856
1904
|
processPolling(elt, handler, triggerSpec);
|
|
1857
1905
|
} else {
|
|
@@ -1860,7 +1908,8 @@ return (function () {
|
|
|
1860
1908
|
}
|
|
1861
1909
|
|
|
1862
1910
|
function evalScript(script) {
|
|
1863
|
-
if (htmx.config.allowScriptTags &&
|
|
1911
|
+
if (!script.htmxExecuted && htmx.config.allowScriptTags &&
|
|
1912
|
+
(script.type === "text/javascript" || script.type === "module" || script.type === "") ) {
|
|
1864
1913
|
var newScript = getDocument().createElement("script");
|
|
1865
1914
|
forEach(script.attributes, function (attr) {
|
|
1866
1915
|
newScript.setAttribute(attr.name, attr.value);
|
|
@@ -1894,26 +1943,35 @@ return (function () {
|
|
|
1894
1943
|
});
|
|
1895
1944
|
}
|
|
1896
1945
|
|
|
1897
|
-
function
|
|
1898
|
-
|
|
1946
|
+
function shouldProcessHxOn(elt) {
|
|
1947
|
+
var attributes = elt.attributes
|
|
1948
|
+
for (var j = 0; j < attributes.length; j++) {
|
|
1949
|
+
var attrName = attributes[j].name
|
|
1950
|
+
if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:") ||
|
|
1951
|
+
startsWith(attrName, "hx-on-") || startsWith(attrName, "data-hx-on-")) {
|
|
1952
|
+
return true
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
return false
|
|
1899
1956
|
}
|
|
1900
1957
|
|
|
1901
1958
|
function findHxOnWildcardElements(elt) {
|
|
1902
1959
|
var node = null
|
|
1903
1960
|
var elements = []
|
|
1904
1961
|
|
|
1962
|
+
if (shouldProcessHxOn(elt)) {
|
|
1963
|
+
elements.push(elt)
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1905
1966
|
if (document.evaluate) {
|
|
1906
|
-
var iter = document.evaluate('
|
|
1967
|
+
var iter = document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or' +
|
|
1968
|
+
' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]', elt)
|
|
1907
1969
|
while (node = iter.iterateNext()) elements.push(node)
|
|
1908
1970
|
} else {
|
|
1909
|
-
var allElements =
|
|
1971
|
+
var allElements = elt.getElementsByTagName("*")
|
|
1910
1972
|
for (var i = 0; i < allElements.length; i++) {
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
var attrName = attributes[j].name
|
|
1914
|
-
if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:")) {
|
|
1915
|
-
elements.push(allElements[i])
|
|
1916
|
-
}
|
|
1973
|
+
if (shouldProcessHxOn(allElements[i])) {
|
|
1974
|
+
elements.push(allElements[i])
|
|
1917
1975
|
}
|
|
1918
1976
|
}
|
|
1919
1977
|
}
|
|
@@ -1923,8 +1981,8 @@ return (function () {
|
|
|
1923
1981
|
|
|
1924
1982
|
function findElementsToProcess(elt) {
|
|
1925
1983
|
if (elt.querySelectorAll) {
|
|
1926
|
-
var
|
|
1927
|
-
var results = elt.querySelectorAll(VERB_SELECTOR +
|
|
1984
|
+
var boostedSelector = ", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]";
|
|
1985
|
+
var results = elt.querySelectorAll(VERB_SELECTOR + boostedSelector + ", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws]," +
|
|
1928
1986
|
" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");
|
|
1929
1987
|
return results;
|
|
1930
1988
|
} else {
|
|
@@ -1970,7 +2028,7 @@ return (function () {
|
|
|
1970
2028
|
function countCurlies(line) {
|
|
1971
2029
|
var tokens = tokenizeString(line);
|
|
1972
2030
|
var netCurlies = 0;
|
|
1973
|
-
for (
|
|
2031
|
+
for (var i = 0; i < tokens.length; i++) {
|
|
1974
2032
|
const token = tokens[i];
|
|
1975
2033
|
if (token === "{") {
|
|
1976
2034
|
netCurlies++;
|
|
@@ -2032,12 +2090,22 @@ return (function () {
|
|
|
2032
2090
|
for (var i = 0; i < elt.attributes.length; i++) {
|
|
2033
2091
|
var name = elt.attributes[i].name
|
|
2034
2092
|
var value = elt.attributes[i].value
|
|
2035
|
-
if (startsWith(name, "hx-on
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
if (
|
|
2093
|
+
if (startsWith(name, "hx-on") || startsWith(name, "data-hx-on")) {
|
|
2094
|
+
var afterOnPosition = name.indexOf("-on") + 3;
|
|
2095
|
+
var nextChar = name.slice(afterOnPosition, afterOnPosition + 1);
|
|
2096
|
+
if (nextChar === "-" || nextChar === ":") {
|
|
2097
|
+
var eventName = name.slice(afterOnPosition + 1);
|
|
2098
|
+
// if the eventName starts with a colon or dash, prepend "htmx" for shorthand support
|
|
2099
|
+
if (startsWith(eventName, ":")) {
|
|
2100
|
+
eventName = "htmx" + eventName
|
|
2101
|
+
} else if (startsWith(eventName, "-")) {
|
|
2102
|
+
eventName = "htmx:" + eventName.slice(1);
|
|
2103
|
+
} else if (startsWith(eventName, "htmx-")) {
|
|
2104
|
+
eventName = "htmx:" + eventName.slice(5);
|
|
2105
|
+
}
|
|
2039
2106
|
|
|
2040
|
-
|
|
2107
|
+
addHxOnEventHandler(elt, eventName, value)
|
|
2108
|
+
}
|
|
2041
2109
|
}
|
|
2042
2110
|
}
|
|
2043
2111
|
}
|
|
@@ -2315,7 +2383,9 @@ return (function () {
|
|
|
2315
2383
|
var details = {path: path, xhr:request};
|
|
2316
2384
|
triggerEvent(getDocument().body, "htmx:historyCacheMiss", details);
|
|
2317
2385
|
request.open('GET', path, true);
|
|
2386
|
+
request.setRequestHeader("HX-Request", "true");
|
|
2318
2387
|
request.setRequestHeader("HX-History-Restore-Request", "true");
|
|
2388
|
+
request.setRequestHeader("HX-Current-URL", getDocument().location.href);
|
|
2319
2389
|
request.onload = function () {
|
|
2320
2390
|
if (this.status >= 200 && this.status < 400) {
|
|
2321
2391
|
triggerEvent(getDocument().body, "htmx:historyCacheMissLoad", details);
|
|
@@ -2430,7 +2500,7 @@ return (function () {
|
|
|
2430
2500
|
}
|
|
2431
2501
|
|
|
2432
2502
|
function shouldInclude(elt) {
|
|
2433
|
-
if(elt.name === "" || elt.name == null || elt.disabled) {
|
|
2503
|
+
if(elt.name === "" || elt.name == null || elt.disabled || closest(elt, "fieldset[disabled]")) {
|
|
2434
2504
|
return false;
|
|
2435
2505
|
}
|
|
2436
2506
|
// ignore "submitter" types (see jQuery src/serialize.js)
|
|
@@ -2906,7 +2976,7 @@ return (function () {
|
|
|
2906
2976
|
}
|
|
2907
2977
|
|
|
2908
2978
|
function hasHeader(xhr, regexp) {
|
|
2909
|
-
return xhr.getAllResponseHeaders()
|
|
2979
|
+
return regexp.test(xhr.getAllResponseHeaders())
|
|
2910
2980
|
}
|
|
2911
2981
|
|
|
2912
2982
|
function ajaxHelper(verb, path, context) {
|
|
@@ -3453,7 +3523,11 @@ return (function () {
|
|
|
3453
3523
|
}
|
|
3454
3524
|
|
|
3455
3525
|
if (hasHeader(xhr,/HX-Retarget:/i)) {
|
|
3456
|
-
|
|
3526
|
+
if (xhr.getResponseHeader("HX-Retarget") === "this") {
|
|
3527
|
+
responseInfo.target = elt;
|
|
3528
|
+
} else {
|
|
3529
|
+
responseInfo.target = querySelectorExt(elt, xhr.getResponseHeader("HX-Retarget"));
|
|
3530
|
+
}
|
|
3457
3531
|
}
|
|
3458
3532
|
|
|
3459
3533
|
var historyUpdate = determineHistoryUpdates(elt, responseInfo);
|
|
@@ -3752,34 +3826,25 @@ return (function () {
|
|
|
3752
3826
|
//====================================================================
|
|
3753
3827
|
// Initialization
|
|
3754
3828
|
//====================================================================
|
|
3829
|
+
var isReady = false
|
|
3830
|
+
getDocument().addEventListener('DOMContentLoaded', function() {
|
|
3831
|
+
isReady = true
|
|
3832
|
+
})
|
|
3833
|
+
|
|
3755
3834
|
/**
|
|
3756
|
-
*
|
|
3757
|
-
*
|
|
3758
|
-
*
|
|
3835
|
+
* Execute a function now if DOMContentLoaded has fired, otherwise listen for it.
|
|
3836
|
+
*
|
|
3837
|
+
* This function uses isReady because there is no realiable way to ask the browswer whether
|
|
3838
|
+
* the DOMContentLoaded event has already been fired; there's a gap between DOMContentLoaded
|
|
3839
|
+
* firing and readystate=complete.
|
|
3759
3840
|
*/
|
|
3760
|
-
function ready(
|
|
3761
|
-
//
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
if (getDocument().readyState === "complete") {
|
|
3769
|
-
// DOMContentLoaded definitely fired, we can initialize the page
|
|
3770
|
-
callReadyFunction();
|
|
3771
|
-
}
|
|
3772
|
-
else {
|
|
3773
|
-
/* DOMContentLoaded *maybe* already fired, wait for
|
|
3774
|
-
* the next DOMContentLoaded or readystatechange event
|
|
3775
|
-
*/
|
|
3776
|
-
getDocument().addEventListener("DOMContentLoaded", function() {
|
|
3777
|
-
callReadyFunction();
|
|
3778
|
-
});
|
|
3779
|
-
getDocument().addEventListener("readystatechange", function() {
|
|
3780
|
-
if (getDocument().readyState !== "complete") return;
|
|
3781
|
-
callReadyFunction();
|
|
3782
|
-
});
|
|
3841
|
+
function ready(fn) {
|
|
3842
|
+
// Checking readyState here is a failsafe in case the htmx script tag entered the DOM by
|
|
3843
|
+
// some means other than the initial page load.
|
|
3844
|
+
if (isReady || getDocument().readyState === 'complete') {
|
|
3845
|
+
fn();
|
|
3846
|
+
} else {
|
|
3847
|
+
getDocument().addEventListener('DOMContentLoaded', fn);
|
|
3783
3848
|
}
|
|
3784
3849
|
}
|
|
3785
3850
|
|
|
@@ -3827,7 +3892,9 @@ return (function () {
|
|
|
3827
3892
|
internalData.xhr.abort();
|
|
3828
3893
|
}
|
|
3829
3894
|
});
|
|
3830
|
-
|
|
3895
|
+
/** @type {(ev: PopStateEvent) => any} */
|
|
3896
|
+
const originalPopstate = window.onpopstate ? window.onpopstate.bind(window) : null;
|
|
3897
|
+
/** @type {(ev: PopStateEvent) => any} */
|
|
3831
3898
|
window.onpopstate = function (event) {
|
|
3832
3899
|
if (event.state && event.state.htmx) {
|
|
3833
3900
|
restoreHistory();
|