Dep: htmx version update
This commit is contained in:
		
							
								
								
									
										2
									
								
								assets/htmx.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								assets/htmx.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -6,350 +6,285 @@ This extension adds support for Server Sent Events to htmx.  See /www/extensions | |||||||
| */ | */ | ||||||
|  |  | ||||||
| (function() { | (function() { | ||||||
|  |   /** @type {import("../htmx").HtmxInternalApi} */ | ||||||
|  |   var api | ||||||
|  |  | ||||||
| 	/** @type {import("../htmx").HtmxInternalApi} */ |   htmx.defineExtension('sse', { | ||||||
| 	var api; |  | ||||||
|  |  | ||||||
| 	htmx.defineExtension("sse", { |     /** | ||||||
|  |      * Init saves the provided reference to the internal HTMX API. | ||||||
|  |      * | ||||||
|  |      * @param {import("../htmx").HtmxInternalApi} api | ||||||
|  |      * @returns void | ||||||
|  |      */ | ||||||
|  |     init: function(apiRef) { | ||||||
|  |       // store a reference to the internal API. | ||||||
|  |       api = apiRef | ||||||
|  |  | ||||||
| 		/** |       // set a function in the public API for creating new EventSource objects | ||||||
| 		 * Init saves the provided reference to the internal HTMX API. |       if (htmx.createEventSource == undefined) { | ||||||
| 		 *  |         htmx.createEventSource = createEventSource | ||||||
| 		 * @param {import("../htmx").HtmxInternalApi} api  |       } | ||||||
| 		 * @returns void |     }, | ||||||
| 		 */ |  | ||||||
| 		init: function(apiRef) { |  | ||||||
| 			// store a reference to the internal API. |  | ||||||
| 			api = apiRef; |  | ||||||
|  |  | ||||||
| 			// set a function in the public API for creating new EventSource objects |     getSelectors: function() { | ||||||
| 			if (htmx.createEventSource == undefined) { |       return ['[sse-connect]', '[data-sse-connect]', '[sse-swap]', '[data-sse-swap]'] | ||||||
| 				htmx.createEventSource = createEventSource; |     }, | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
|  |  | ||||||
| 		/** |     /** | ||||||
| 		 * onEvent handles all events passed to this extension. |      * onEvent handles all events passed to this extension. | ||||||
| 		 *  |      * | ||||||
| 		 * @param {string} name  |      * @param {string} name | ||||||
| 		 * @param {Event} evt  |      * @param {Event} evt | ||||||
| 		 * @returns void |      * @returns void | ||||||
| 		 */ |      */ | ||||||
| 		onEvent: function(name, evt) { |     onEvent: function(name, evt) { | ||||||
|  |       var parent = evt.target || evt.detail.elt | ||||||
|  |       switch (name) { | ||||||
|  |         case 'htmx:beforeCleanupElement': | ||||||
|  |           var internalData = api.getInternalData(parent) | ||||||
|  |           // Try to remove remove an EventSource when elements are removed | ||||||
|  |           var source = internalData.sseEventSource | ||||||
|  |           if (source) { | ||||||
|  |             api.triggerEvent(parent, 'htmx:sseClose', { | ||||||
|  |               source, | ||||||
|  |               type: 'nodeReplaced', | ||||||
|  |             }) | ||||||
|  |             internalData.sseEventSource.close() | ||||||
|  |           } | ||||||
|  |  | ||||||
| 			switch (name) { |           return | ||||||
|  |  | ||||||
| 				case "htmx:beforeCleanupElement": |         // Try to create EventSources when elements are processed | ||||||
| 					var internalData = api.getInternalData(evt.target) |         case 'htmx:afterProcessNode': | ||||||
| 					// Try to remove remove an EventSource when elements are removed |           ensureEventSourceOnElement(parent) | ||||||
| 					if (internalData.sseEventSource) { |       } | ||||||
| 						internalData.sseEventSource.close(); |     } | ||||||
| 					} |   }) | ||||||
|  |  | ||||||
| 					return; |   /// //////////////////////////////////////////// | ||||||
|  |   // HELPER FUNCTIONS | ||||||
|  |   /// //////////////////////////////////////////// | ||||||
|  |  | ||||||
| 				// Try to create EventSources when elements are processed |   /** | ||||||
| 				case "htmx:afterProcessNode": |    * createEventSource is the default method for creating new EventSource objects. | ||||||
| 					ensureEventSourceOnElement(evt.target); |    * it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed. | ||||||
| 					registerSSE(evt.target); |    * | ||||||
| 			} |    * @param {string} url | ||||||
| 		} |    * @returns EventSource | ||||||
| 	}); |    */ | ||||||
|  |   function createEventSource(url) { | ||||||
|  |     return new EventSource(url, { withCredentials: true }) | ||||||
|  |   } | ||||||
|  |  | ||||||
| 	/////////////////////////////////////////////// |   /** | ||||||
| 	// HELPER FUNCTIONS |    * registerSSE looks for attributes that can contain sse events, right | ||||||
| 	/////////////////////////////////////////////// |    * now hx-trigger and sse-swap and adds listeners based on these attributes too | ||||||
|  |    * the closest event source | ||||||
|  |    * | ||||||
|  |    * @param {HTMLElement} elt | ||||||
|  |    */ | ||||||
|  |   function registerSSE(elt) { | ||||||
|  |     // Add message handlers for every `sse-swap` attribute | ||||||
|  |     if (api.getAttributeValue(elt, 'sse-swap')) { | ||||||
|  |       // Find closest existing event source | ||||||
|  |       var sourceElement = api.getClosestMatch(elt, hasEventSource) | ||||||
|  |       if (sourceElement == null) { | ||||||
|  |         // api.triggerErrorEvent(elt, "htmx:noSSESourceError") | ||||||
|  |         return null // no eventsource in parentage, orphaned element | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Set internalData and source | ||||||
|  |       var internalData = api.getInternalData(sourceElement) | ||||||
|  |       var source = internalData.sseEventSource | ||||||
|  |  | ||||||
|  |       var sseSwapAttr = api.getAttributeValue(elt, 'sse-swap') | ||||||
|  |       var sseEventNames = sseSwapAttr.split(',') | ||||||
|  |  | ||||||
|  |       for (var i = 0; i < sseEventNames.length; i++) { | ||||||
|  |         const sseEventName = sseEventNames[i].trim() | ||||||
|  |         const listener = function(event) { | ||||||
|  |           // If the source is missing then close SSE | ||||||
|  |           if (maybeCloseSSESource(sourceElement)) { | ||||||
|  |             return | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           // If the body no longer contains the element, remove the listener | ||||||
|  |           if (!api.bodyContains(elt)) { | ||||||
|  |             source.removeEventListener(sseEventName, listener) | ||||||
|  |             return | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           // swap the response into the DOM and trigger a notification | ||||||
|  |           if (!api.triggerEvent(elt, 'htmx:sseBeforeMessage', event)) { | ||||||
|  |             return | ||||||
|  |           } | ||||||
|  |           swap(elt, event.data) | ||||||
|  |           api.triggerEvent(elt, 'htmx:sseMessage', event) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Register the new listener | ||||||
|  |         api.getInternalData(elt).sseEventListener = listener | ||||||
|  |         source.addEventListener(sseEventName, listener) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Add message handlers for every `hx-trigger="sse:*"` attribute | ||||||
|  |     if (api.getAttributeValue(elt, 'hx-trigger')) { | ||||||
|  |       // Find closest existing event source | ||||||
|  |       var sourceElement = api.getClosestMatch(elt, hasEventSource) | ||||||
|  |       if (sourceElement == null) { | ||||||
|  |         // api.triggerErrorEvent(elt, "htmx:noSSESourceError") | ||||||
|  |         return null // no eventsource in parentage, orphaned element | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Set internalData and source | ||||||
|  |       var internalData = api.getInternalData(sourceElement) | ||||||
|  |       var source = internalData.sseEventSource | ||||||
|  |  | ||||||
|  |       var triggerSpecs = api.getTriggerSpecs(elt) | ||||||
|  |       triggerSpecs.forEach(function(ts) { | ||||||
|  |         if (ts.trigger.slice(0, 4) !== 'sse:') { | ||||||
|  |           return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         var listener = function (event) { | ||||||
|  |           if (maybeCloseSSESource(sourceElement)) { | ||||||
|  |             return | ||||||
|  |           } | ||||||
|  |           if (!api.bodyContains(elt)) { | ||||||
|  |             source.removeEventListener(ts.trigger.slice(4), listener) | ||||||
|  |           } | ||||||
|  |           // Trigger events to be handled by the rest of htmx | ||||||
|  |           htmx.trigger(elt, ts.trigger, event) | ||||||
|  |           htmx.trigger(elt, 'htmx:sseMessage', event) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Register the new listener | ||||||
|  |         api.getInternalData(elt).sseEventListener = listener | ||||||
|  |         source.addEventListener(ts.trigger.slice(4), listener) | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * ensureEventSourceOnElement creates a new EventSource connection on the provided element. | ||||||
|  |    * If a usable EventSource already exists, then it is returned.  If not, then a new EventSource | ||||||
|  |    * is created and stored in the element's internalData. | ||||||
|  |    * @param {HTMLElement} elt | ||||||
|  |    * @param {number} retryCount | ||||||
|  |    * @returns {EventSource | null} | ||||||
|  |    */ | ||||||
|  |   function ensureEventSourceOnElement(elt, retryCount) { | ||||||
|  |     if (elt == null) { | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // handle extension source creation attribute | ||||||
|  |     if (api.getAttributeValue(elt, 'sse-connect')) { | ||||||
|  |       var sseURL = api.getAttributeValue(elt, 'sse-connect') | ||||||
|  |       if (sseURL == null) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ensureEventSource(elt, sseURL, retryCount) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     registerSSE(elt) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function ensureEventSource(elt, url, retryCount) { | ||||||
|  |     var source = htmx.createEventSource(url) | ||||||
|  |  | ||||||
|  |     source.onerror = function(err) { | ||||||
|  |       // Log an error event | ||||||
|  |       api.triggerErrorEvent(elt, 'htmx:sseError', { error: err, source }) | ||||||
|  |  | ||||||
|  |       // If parent no longer exists in the document, then clean up this EventSource | ||||||
|  |       if (maybeCloseSSESource(elt)) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       // Otherwise, try to reconnect the EventSource | ||||||
|  |       if (source.readyState === EventSource.CLOSED) { | ||||||
|  |         retryCount = retryCount || 0 | ||||||
|  |         retryCount = Math.max(Math.min(retryCount * 2, 128), 1) | ||||||
|  |         var timeout = retryCount * 500 | ||||||
|  |         window.setTimeout(function() { | ||||||
|  |           ensureEventSourceOnElement(elt, retryCount) | ||||||
|  |         }, timeout) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     source.onopen = function(evt) { | ||||||
|  |       api.triggerEvent(elt, 'htmx:sseOpen', { source }) | ||||||
|  |  | ||||||
|  |       if (retryCount && retryCount > 0) { | ||||||
|  |         const childrenToFix = elt.querySelectorAll("[sse-swap], [data-sse-swap], [hx-trigger], [data-hx-trigger]") | ||||||
|  |         for (let i = 0; i < childrenToFix.length; i++) { | ||||||
|  |           registerSSE(childrenToFix[i]) | ||||||
|  |         } | ||||||
|  |         // We want to increase the reconnection delay for consecutive failed attempts only | ||||||
|  |         retryCount = 0 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     api.getInternalData(elt).sseEventSource = source | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/** |     var closeAttribute = api.getAttributeValue(elt, "sse-close"); | ||||||
| 	 * createEventSource is the default method for creating new EventSource objects. |     if (closeAttribute) { | ||||||
| 	 * it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed. |       // close eventsource when this message is received | ||||||
| 	 *  |       source.addEventListener(closeAttribute, function() { | ||||||
| 	 * @param {string} url  |         api.triggerEvent(elt, 'htmx:sseClose', { | ||||||
| 	 * @returns EventSource |           source, | ||||||
| 	 */ |           type: 'message', | ||||||
| 	function createEventSource(url) { |         }) | ||||||
| 		return new EventSource(url, { withCredentials: true }); |         source.close() | ||||||
| 	} |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
| 	function splitOnWhitespace(trigger) { |   /** | ||||||
| 		return trigger.trim().split(/\s+/); |    * maybeCloseSSESource confirms that the parent element still exists. | ||||||
| 	} |    * If not, then any associated SSE source is closed and the function returns true. | ||||||
|  |    * | ||||||
|  |    * @param {HTMLElement} elt | ||||||
|  |    * @returns boolean | ||||||
|  |    */ | ||||||
|  |   function maybeCloseSSESource(elt) { | ||||||
|  |     if (!api.bodyContains(elt)) { | ||||||
|  |       var source = api.getInternalData(elt).sseEventSource | ||||||
|  |       if (source != undefined) { | ||||||
|  |         api.triggerEvent(elt, 'htmx:sseClose', { | ||||||
|  |           source, | ||||||
|  |           type: 'nodeMissing', | ||||||
|  |         }) | ||||||
|  |         source.close() | ||||||
|  |         // source = null | ||||||
|  |         return true | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  |  | ||||||
| 	function getLegacySSEURL(elt) { |  | ||||||
| 		var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); |  | ||||||
| 		if (legacySSEValue) { |  | ||||||
| 			var values = splitOnWhitespace(legacySSEValue); |  | ||||||
| 			for (var i = 0; i < values.length; i++) { |  | ||||||
| 				var value = values[i].split(/:(.+)/); |  | ||||||
| 				if (value[0] === "connect") { |  | ||||||
| 					return value[1]; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function getLegacySSESwaps(elt) { |   /** | ||||||
| 		var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); |    * @param {HTMLElement} elt | ||||||
| 		var returnArr = []; |    * @param {string} content | ||||||
| 		if (legacySSEValue != null) { |    */ | ||||||
| 			var values = splitOnWhitespace(legacySSEValue); |   function swap(elt, content) { | ||||||
| 			for (var i = 0; i < values.length; i++) { |     api.withExtensions(elt, function(extension) { | ||||||
| 				var value = values[i].split(/:(.+)/); |       content = extension.transformResponse(content, null, elt) | ||||||
| 				if (value[0] === "swap") { |     }) | ||||||
| 					returnArr.push(value[1]); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return returnArr; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |     var swapSpec = api.getSwapSpecification(elt) | ||||||
| 	 * registerSSE looks for attributes that can contain sse events, right  |     var target = api.getTarget(elt) | ||||||
| 	 * now hx-trigger and sse-swap and adds listeners based on these attributes too |     api.swap(target, content, swapSpec) | ||||||
| 	 * the closest event source |   } | ||||||
| 	 * |  | ||||||
| 	 * @param {HTMLElement} elt |  | ||||||
| 	 */ |  | ||||||
| 	function registerSSE(elt) { |  | ||||||
| 		// Find closest existing event source |  | ||||||
| 		var sourceElement = api.getClosestMatch(elt, hasEventSource); |  | ||||||
| 		if (sourceElement == null) { |  | ||||||
| 			// api.triggerErrorEvent(elt, "htmx:noSSESourceError") |  | ||||||
| 			return null; // no eventsource in parentage, orphaned element |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Set internalData and source |  | ||||||
| 		var internalData = api.getInternalData(sourceElement); |  | ||||||
| 		var source = internalData.sseEventSource; |  | ||||||
|  |  | ||||||
| 		// Add message handlers for every `sse-swap` attribute |   function hasEventSource(node) { | ||||||
| 		queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) { |     return api.getInternalData(node).sseEventSource != null | ||||||
|  |   } | ||||||
| 			var sseSwapAttr = api.getAttributeValue(child, "sse-swap"); | })() | ||||||
| 			if (sseSwapAttr) { |  | ||||||
| 				var sseEventNames = sseSwapAttr.split(","); |  | ||||||
| 			} else { |  | ||||||
| 				var sseEventNames = getLegacySSESwaps(child); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			for (var i = 0; i < sseEventNames.length; i++) { |  | ||||||
| 				var sseEventName = sseEventNames[i].trim(); |  | ||||||
| 				var listener = function(event) { |  | ||||||
|  |  | ||||||
| 					// If the source is missing then close SSE |  | ||||||
| 					if (maybeCloseSSESource(sourceElement)) { |  | ||||||
| 						return; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					// If the body no longer contains the element, remove the listener |  | ||||||
| 					if (!api.bodyContains(child)) { |  | ||||||
| 						source.removeEventListener(sseEventName, listener); |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					// swap the response into the DOM and trigger a notification |  | ||||||
| 					swap(child, event.data); |  | ||||||
| 					api.triggerEvent(elt, "htmx:sseMessage", event); |  | ||||||
| 				}; |  | ||||||
|  |  | ||||||
| 				// Register the new listener |  | ||||||
| 				api.getInternalData(child).sseEventListener = listener; |  | ||||||
| 				source.addEventListener(sseEventName, listener); |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		// Add message handlers for every `hx-trigger="sse:*"` attribute |  | ||||||
| 		queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) { |  | ||||||
|  |  | ||||||
| 			var sseEventName = api.getAttributeValue(child, "hx-trigger"); |  | ||||||
| 			if (sseEventName == null) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			// Only process hx-triggers for events with the "sse:" prefix |  | ||||||
| 			if (sseEventName.slice(0, 4) != "sse:") { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 			 |  | ||||||
| 			// remove the sse: prefix from here on out |  | ||||||
| 			sseEventName = sseEventName.substr(4); |  | ||||||
|  |  | ||||||
| 			var listener = function() { |  | ||||||
| 				if (maybeCloseSSESource(sourceElement)) { |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				if (!api.bodyContains(child)) { |  | ||||||
| 					source.removeEventListener(sseEventName, listener); |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * ensureEventSourceOnElement creates a new EventSource connection on the provided element. |  | ||||||
| 	 * If a usable EventSource already exists, then it is returned.  If not, then a new EventSource |  | ||||||
| 	 * is created and stored in the element's internalData. |  | ||||||
| 	 * @param {HTMLElement} elt |  | ||||||
| 	 * @param {number} retryCount |  | ||||||
| 	 * @returns {EventSource | null} |  | ||||||
| 	 */ |  | ||||||
| 	function ensureEventSourceOnElement(elt, retryCount) { |  | ||||||
|  |  | ||||||
| 		if (elt == null) { |  | ||||||
| 			return null; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// handle extension source creation attribute |  | ||||||
| 		queryAttributeOnThisOrChildren(elt, "sse-connect").forEach(function(child) { |  | ||||||
| 			var sseURL = api.getAttributeValue(child, "sse-connect"); |  | ||||||
| 			if (sseURL == null) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ensureEventSource(child, sseURL, retryCount); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		// handle legacy sse, remove for HTMX2 |  | ||||||
| 		queryAttributeOnThisOrChildren(elt, "hx-sse").forEach(function(child) { |  | ||||||
| 			var sseURL = getLegacySSEURL(child); |  | ||||||
| 			if (sseURL == null) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			ensureEventSource(child, sseURL, retryCount); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function ensureEventSource(elt, url, retryCount) { |  | ||||||
| 		var source = htmx.createEventSource(url); |  | ||||||
|  |  | ||||||
| 		source.onerror = function(err) { |  | ||||||
|  |  | ||||||
| 			// Log an error event |  | ||||||
| 			api.triggerErrorEvent(elt, "htmx:sseError", { error: err, source: source }); |  | ||||||
|  |  | ||||||
| 			// If parent no longer exists in the document, then clean up this EventSource |  | ||||||
| 			if (maybeCloseSSESource(elt)) { |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			// Otherwise, try to reconnect the EventSource |  | ||||||
| 			if (source.readyState === EventSource.CLOSED) { |  | ||||||
| 				retryCount = retryCount || 0; |  | ||||||
| 				var timeout = Math.random() * (2 ^ retryCount) * 500; |  | ||||||
| 				window.setTimeout(function() { |  | ||||||
| 					ensureEventSourceOnElement(elt, Math.min(7, retryCount + 1)); |  | ||||||
| 				}, timeout); |  | ||||||
| 			} |  | ||||||
| 		}; |  | ||||||
|  |  | ||||||
| 		source.onopen = function(evt) { |  | ||||||
| 			api.triggerEvent(elt, "htmx:sseOpen", { source: source }); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		api.getInternalData(elt).sseEventSource = source; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * maybeCloseSSESource confirms that the parent element still exists. |  | ||||||
| 	 * If not, then any associated SSE source is closed and the function returns true. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param {HTMLElement} elt  |  | ||||||
| 	 * @returns boolean |  | ||||||
| 	 */ |  | ||||||
| 	function maybeCloseSSESource(elt) { |  | ||||||
| 		if (!api.bodyContains(elt)) { |  | ||||||
| 			var source = api.getInternalData(elt).sseEventSource; |  | ||||||
| 			if (source != undefined) { |  | ||||||
| 				source.close(); |  | ||||||
| 				// source = null |  | ||||||
| 				return true; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT. |  | ||||||
| 	 *  |  | ||||||
| 	 * @param {HTMLElement} elt  |  | ||||||
| 	 * @param {string} attributeName  |  | ||||||
| 	 */ |  | ||||||
| 	function queryAttributeOnThisOrChildren(elt, attributeName) { |  | ||||||
|  |  | ||||||
| 		var result = []; |  | ||||||
|  |  | ||||||
| 		// If the parent element also contains the requested attribute, then add it to the results too. |  | ||||||
| 		if (api.hasAttribute(elt, attributeName)) { |  | ||||||
| 			result.push(elt); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		// Search all child nodes that match the requested attribute |  | ||||||
| 		elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "]").forEach(function(node) { |  | ||||||
| 			result.push(node); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		return result; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * @param {HTMLElement} elt |  | ||||||
| 	 * @param {string} content  |  | ||||||
| 	 */ |  | ||||||
| 	function swap(elt, content) { |  | ||||||
|  |  | ||||||
| 		api.withExtensions(elt, function(extension) { |  | ||||||
| 			content = extension.transformResponse(content, null, elt); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		var swapSpec = api.getSwapSpecification(elt); |  | ||||||
| 		var target = api.getTarget(elt); |  | ||||||
| 		var settleInfo = api.makeSettleInfo(elt); |  | ||||||
|  |  | ||||||
| 		api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo); |  | ||||||
|  |  | ||||||
| 		settleInfo.elts.forEach(function(elt) { |  | ||||||
| 			if (elt.classList) { |  | ||||||
| 				elt.classList.add(htmx.config.settlingClass); |  | ||||||
| 			} |  | ||||||
| 			api.triggerEvent(elt, 'htmx:beforeSettle'); |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		// Handle settle tasks (with delay if requested) |  | ||||||
| 		if (swapSpec.settleDelay > 0) { |  | ||||||
| 			setTimeout(doSettle(settleInfo), swapSpec.settleDelay); |  | ||||||
| 		} else { |  | ||||||
| 			doSettle(settleInfo)(); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * doSettle mirrors much of the functionality in htmx that  |  | ||||||
| 	 * settles elements after their content has been swapped. |  | ||||||
| 	 * TODO: this should be published by htmx, and not duplicated here |  | ||||||
| 	 * @param {import("../htmx").HtmxSettleInfo} settleInfo  |  | ||||||
| 	 * @returns () => void |  | ||||||
| 	 */ |  | ||||||
| 	function doSettle(settleInfo) { |  | ||||||
|  |  | ||||||
| 		return function() { |  | ||||||
| 			settleInfo.tasks.forEach(function(task) { |  | ||||||
| 				task.call(); |  | ||||||
| 			}); |  | ||||||
|  |  | ||||||
| 			settleInfo.elts.forEach(function(elt) { |  | ||||||
| 				if (elt.classList) { |  | ||||||
| 					elt.classList.remove(htmx.config.settlingClass); |  | ||||||
| 				} |  | ||||||
| 				api.triggerEvent(elt, 'htmx:afterSettle'); |  | ||||||
| 			}); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	function hasEventSource(node) { |  | ||||||
| 		return api.getInternalData(node).sseEventSource != null; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| })(); |  | ||||||
|   | |||||||
| @@ -3,13 +3,12 @@ | |||||||
| <html lang="en"> | <html lang="en"> | ||||||
| <head> | <head> | ||||||
| 	<title>Alias</title> | 	<title>Alias</title> | ||||||
| 	<script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script> |  | ||||||
| 	<script src="/assets/htmx.min.js"></script> | 	<script src="/assets/htmx.min.js"></script> | ||||||
| 	<script src="/assets/htmx.sse.js"></script> | 	<script src="/assets/htmx.sse.js"></script> | ||||||
|         <script src="/assets/tailwind.css"></script> |         <script src="/assets/tailwind.css"></script> | ||||||
| 	<link rel="stylesheet" href="/assets/style.css"/> | 	<link rel="stylesheet" href="/assets/style.css"/> | ||||||
| 	<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1"/> | 	<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1"/> | ||||||
| 	<link rel="icon" sizes="64x64" href="favicon.ico"/> | 	<link rel="icon" sizes="64x64" href="/assets/favicon/wolfhead_negated.ico"/> | ||||||
| 	<style type="text/css"> | 	<style type="text/css"> | ||||||
| 		body{ | 		body{ | ||||||
|             background-color: #0C1616FF; |             background-color: #0C1616FF; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder