summaryrefslogtreecommitdiffstatshomepage
path: root/www/test/1.8.6/src/ext/loading-states.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/test/1.8.6/src/ext/loading-states.js')
-rw-r--r--www/test/1.8.6/src/ext/loading-states.js179
1 files changed, 179 insertions, 0 deletions
diff --git a/www/test/1.8.6/src/ext/loading-states.js b/www/test/1.8.6/src/ext/loading-states.js
new file mode 100644
index 00000000..20f7d3bf
--- /dev/null
+++ b/www/test/1.8.6/src/ext/loading-states.js
@@ -0,0 +1,179 @@
+;(function () {
+ let loadingStatesUndoQueue = []
+
+ function loadingStateContainer(target) {
+ return htmx.closest(target, '[data-loading-states]') || document.body
+ }
+
+ function mayProcessUndoCallback(target, callback) {
+ if (document.body.contains(target)) {
+ callback()
+ }
+ }
+
+ function mayProcessLoadingStateByPath(elt, requestPath) {
+ const pathElt = htmx.closest(elt, '[data-loading-path]')
+ if (!pathElt) {
+ return true
+ }
+
+ return pathElt.getAttribute('data-loading-path') === requestPath
+ }
+
+ function queueLoadingState(sourceElt, targetElt, doCallback, undoCallback) {
+ const delayElt = htmx.closest(sourceElt, '[data-loading-delay]')
+ if (delayElt) {
+ const delayInMilliseconds =
+ delayElt.getAttribute('data-loading-delay') || 200
+ const timeout = setTimeout(() => {
+ doCallback()
+
+ loadingStatesUndoQueue.push(() => {
+ mayProcessUndoCallback(targetElt, () => undoCallback())
+ })
+ }, delayInMilliseconds)
+
+ loadingStatesUndoQueue.push(() => {
+ mayProcessUndoCallback(targetElt, () => clearTimeout(timeout))
+ })
+ } else {
+ doCallback()
+ loadingStatesUndoQueue.push(() => {
+ mayProcessUndoCallback(targetElt, () => undoCallback())
+ })
+ }
+ }
+
+ function getLoadingStateElts(loadingScope, type, path) {
+ return Array.from(htmx.findAll(loadingScope, `[${type}]`)).filter(
+ (elt) => mayProcessLoadingStateByPath(elt, path)
+ )
+ }
+
+ function getLoadingTarget(elt) {
+ if (elt.getAttribute('data-loading-target')) {
+ return Array.from(
+ htmx.findAll(elt.getAttribute('data-loading-target'))
+ )
+ }
+ return [elt]
+ }
+
+ htmx.defineExtension('loading-states', {
+ onEvent: function (name, evt) {
+ if (name === 'htmx:beforeRequest') {
+ const container = loadingStateContainer(evt.target)
+
+ const loadingStateTypes = [
+ 'data-loading',
+ 'data-loading-class',
+ 'data-loading-class-remove',
+ 'data-loading-disable',
+ 'data-loading-aria-busy',
+ ]
+
+ let loadingStateEltsByType = {}
+
+ loadingStateTypes.forEach((type) => {
+ loadingStateEltsByType[type] = getLoadingStateElts(
+ container,
+ type,
+ evt.detail.pathInfo.requestPath
+ )
+ })
+
+ loadingStateEltsByType['data-loading'].forEach((sourceElt) => {
+ getLoadingTarget(sourceElt).forEach((targetElt) => {
+ queueLoadingState(
+ sourceElt,
+ targetElt,
+ () =>
+ (targetElt.style.display =
+ sourceElt.getAttribute('data-loading') ||
+ 'inline-block'),
+ () => (targetElt.style.display = 'none')
+ )
+ })
+ })
+
+ loadingStateEltsByType['data-loading-class'].forEach(
+ (sourceElt) => {
+ const classNames = sourceElt
+ .getAttribute('data-loading-class')
+ .split(' ')
+
+ getLoadingTarget(sourceElt).forEach((targetElt) => {
+ queueLoadingState(
+ sourceElt,
+ targetElt,
+ () =>
+ classNames.forEach((className) =>
+ targetElt.classList.add(className)
+ ),
+ () =>
+ classNames.forEach((className) =>
+ targetElt.classList.remove(className)
+ )
+ )
+ })
+ }
+ )
+
+ loadingStateEltsByType['data-loading-class-remove'].forEach(
+ (sourceElt) => {
+ const classNames = sourceElt
+ .getAttribute('data-loading-class-remove')
+ .split(' ')
+
+ getLoadingTarget(sourceElt).forEach((targetElt) => {
+ queueLoadingState(
+ sourceElt,
+ targetElt,
+ () =>
+ classNames.forEach((className) =>
+ targetElt.classList.remove(className)
+ ),
+ () =>
+ classNames.forEach((className) =>
+ targetElt.classList.add(className)
+ )
+ )
+ })
+ }
+ )
+
+ loadingStateEltsByType['data-loading-disable'].forEach(
+ (sourceElt) => {
+ getLoadingTarget(sourceElt).forEach((targetElt) => {
+ queueLoadingState(
+ sourceElt,
+ targetElt,
+ () => (targetElt.disabled = true),
+ () => (targetElt.disabled = false)
+ )
+ })
+ }
+ )
+
+ loadingStateEltsByType['data-loading-aria-busy'].forEach(
+ (sourceElt) => {
+ getLoadingTarget(sourceElt).forEach((targetElt) => {
+ queueLoadingState(
+ sourceElt,
+ targetElt,
+ () => (targetElt.setAttribute("aria-busy", "true")),
+ () => (targetElt.removeAttribute("aria-busy"))
+ )
+ })
+ }
+ )
+ }
+
+ if (name === 'htmx:beforeOnLoad') {
+ while (loadingStatesUndoQueue.length > 0) {
+ loadingStatesUndoQueue.shift()()
+ }
+ }
+ },
+ })
+})()