1
|
{"version":3,"file":"results.min.js","names":["window","document","imgTimeoutID: number","imageThumbnails: NodeListOf<HTMLImageElement>","copyUrlButton: HTMLButtonElement | null","swipeHorizontal: NodeListOf<HTMLElement>"],"sources":["../../../../../client/simple/node_modules/swiped-events/src/swiped-events.js","../../../../../client/simple/src/js/main/results.ts"],"sourcesContent":["/*!\n * swiped-events.js - v@version@\n * Pure JavaScript swipe events\n * https://github.com/john-doherty/swiped-events\n * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element\n * @author John Doherty <www.johndoherty.info>\n * @license MIT\n */\n(function (window, document) {\n\n 'use strict';\n\n // patch CustomEvent to allow constructor creation (IE/Chrome)\n if (typeof window.CustomEvent !== 'function') {\n\n window.CustomEvent = function (event, params) {\n\n params = params || { bubbles: false, cancelable: false, detail: undefined };\n\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n };\n\n window.CustomEvent.prototype = window.Event.prototype;\n }\n\n document.addEventListener('touchstart', handleTouchStart, false);\n document.addEventListener('touchmove', handleTouchMove, false);\n document.addEventListener('touchend', handleTouchEnd, false);\n\n var xDown = null;\n var yDown = null;\n var xDiff = null;\n var yDiff = null;\n var timeDown = null;\n var startEl = null;\n var touchCount = 0;\n\n /**\n * Fires swiped event if swipe detected on touchend\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchEnd(e) {\n\n // if the user released on a different target, cancel!\n if (startEl !== e.target) return;\n\n var swipeThreshold = parseInt(getNearestAttribute(startEl, 'data-swipe-threshold', '20'), 10); // default 20 units\n var swipeUnit = getNearestAttribute(startEl, 'data-swipe-unit', 'px'); // default px\n var swipeTimeout = parseInt(getNearestAttribute(startEl, 'data-swipe-timeout', '500'), 10); // default 500ms\n var timeDiff = Date.now() - timeDown;\n var eventType = '';\n var changedTouches = e.changedTouches || e.touches || [];\n\n if (swipeUnit === 'vh') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientHeight); // get percentage of viewport height in pixels\n }\n if (swipeUnit === 'vw') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientWidth); // get percentage of viewport height in pixels\n }\n\n if (Math.abs(xDiff) > Math.abs(yDiff)) { // most significant\n if (Math.abs(xDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (xDiff > 0) {\n eventType = 'swiped-left';\n }\n else {\n eventType = 'swiped-right';\n }\n }\n }\n else if (Math.abs(yDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (yDiff > 0) {\n eventType = 'swiped-up';\n }\n else {\n eventType = 'swiped-down';\n }\n }\n\n if (eventType !== '') {\n\n var eventData = {\n dir: eventType.replace(/swiped-/, ''),\n touchType: (changedTouches[0] || {}).touchType || 'direct',\n fingers: touchCount, // Number of fingers used\n xStart: parseInt(xDown, 10),\n xEnd: parseInt((changedTouches[0] || {}).clientX || -1, 10),\n yStart: parseInt(yDown, 10),\n yEnd: parseInt((changedTouches[0] || {}).clientY || -1, 10)\n };\n\n // fire `swiped` event event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData }));\n\n // fire `swiped-dir` event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData }));\n }\n\n // reset values\n xDown = null;\n yDown = null;\n timeDown = null;\n }\n /**\n * Records current location on touchstart event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchStart(e) {\n\n // if the element has data-swipe-ignore=\"true\" we stop listening for swipe events\n if (e.target.getAttribute('data-swipe-ignore') === 'true') return;\n\n startEl = e.target;\n\n timeDown = Date.now();\n xDown = e.touches[0].clientX;\n yDown = e.touches[0].clientY;\n xDiff = 0;\n yDiff = 0;\n touchCount = e.touches.length;\n }\n\n /**\n * Records location diff in px on touchmove event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchMove(e) {\n\n if (!xDown || !yDown) return;\n\n var xUp = e.touches[0].clientX;\n var yUp = e.touches[0].clientY;\n\n xDiff = xDown - xUp;\n yDiff = yDown - yUp;\n }\n\n /**\n * Gets attribute off HTML element or nearest parent\n * @param {object} el - HTML element to retrieve attribute from\n * @param {string} attributeName - name of the attribute\n * @param {any} defaultValue - default value to return if no match found\n * @returns {any} attribute value or defaultValue\n */\n function getNearestAttribute(el, attributeName, defaultValue) {\n\n // walk up the dom tree looking for attributeName\n while (el && el !== document.documentElement) {\n\n var attributeValue = el.getAttribute(attributeName);\n\n if (attributeValue) {\n return attributeValue;\n }\n\n el = el.parentNode;\n }\n\n return defaultValue;\n }\n\n}(window, document));\n","// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport \"../../../node_modules/swiped-events/src/swiped-events.js\";\nimport { assertElement, listen, mutable, settings } from \"../core/toolkit.ts\";\n\nlet imgTimeoutID: number;\n\nconst imageLoader = (resultElement: HTMLElement): void => {\n if (imgTimeoutID) clearTimeout(imgTimeoutID);\n\n const imgElement = resultElement.querySelector<HTMLImageElement>(\".result-images-source img\");\n if (!imgElement) return;\n\n // use thumbnail until full image loads\n const thumbnail = resultElement.querySelector<HTMLImageElement>(\".image_thumbnail\");\n if (thumbnail) {\n if (thumbnail.src === `${settings.theme_static_path}/img/img_load_error.svg`) return;\n\n imgElement.onerror = (): void => {\n imgElement.src = thumbnail.src;\n };\n\n imgElement.src = thumbnail.src;\n }\n\n const imgSource = imgElement.getAttribute(\"data-src\");\n if (!imgSource) return;\n\n // unsafe nodejs specific, cast to https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#return_value\n // https://github.com/searxng/searxng/pull/5073#discussion_r2265767231\n imgTimeoutID = setTimeout(() => {\n imgElement.src = imgSource;\n imgElement.removeAttribute(\"data-src\");\n }, 1000) as unknown as number;\n};\n\nconst imageThumbnails: NodeListOf<HTMLImageElement> =\n document.querySelectorAll<HTMLImageElement>(\"#urls img.image_thumbnail\");\nfor (const thumbnail of imageThumbnails) {\n if (thumbnail.complete && thumbnail.naturalWidth === 0) {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n }\n\n thumbnail.onerror = (): void => {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n };\n}\n\nconst copyUrlButton: HTMLButtonElement | null =\n document.querySelector<HTMLButtonElement>(\"#search_url button#copy_url\");\ncopyUrlButton?.style.setProperty(\"display\", \"block\");\n\nmutable.selectImage = (resultElement: HTMLElement): void => {\n // add a class that can be evaluated in the CSS and indicates that the\n // detail view is open\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.add(\"image-detail-open\");\n\n // add a hash to the browser history so that pressing back doesn't return\n // to the previous page this allows us to dismiss the image details on\n // pressing the back button on mobile devices\n window.location.hash = \"#image-viewer\";\n\n mutable.scrollPageToSelected?.();\n\n // if there is no element given by the caller, stop here\n if (!resultElement) return;\n\n imageLoader(resultElement);\n};\n\nmutable.closeDetail = (): void => {\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.remove(\"image-detail-open\");\n\n // remove #image-viewer hash from url by navigating back\n if (window.location.hash === \"#image-viewer\") {\n window.history.back();\n }\n\n mutable.scrollPageToSelected?.();\n};\n\nlisten(\"click\", \".btn-collapse\", function (this: HTMLElement) {\n const btnLabelCollapsed = this.getAttribute(\"data-btn-text-collapsed\");\n const btnLabelNotCollapsed = this.getAttribute(\"data-btn-text-not-collapsed\");\n const target = this.getAttribute(\"data-target\");\n\n if (!(target && btnLabelCollapsed && btnLabelNotCollapsed)) return;\n\n const targetElement = document.querySelector<HTMLElement>(target);\n assertElement(targetElement);\n\n const isCollapsed = this.classList.contains(\"collapsed\");\n const newLabel = isCollapsed ? btnLabelNotCollapsed : btnLabelCollapsed;\n const oldLabel = isCollapsed ? btnLabelCollapsed : btnLabelNotCollapsed;\n\n this.innerHTML = this.innerHTML.replace(oldLabel, newLabel);\n this.classList.toggle(\"collapsed\");\n\n targetElement.classList.toggle(\"invisible\");\n});\n\nlisten(\"click\", \".media-loader\", function (this: HTMLElement) {\n const target = this.getAttribute(\"data-target\");\n if (!target) return;\n\n const iframeLoad = document.querySelector<HTMLIFrameElement>(`${target} > iframe`);\n assertElement(iframeLoad);\n\n const srctest = iframeLoad.getAttribute(\"src\");\n if (!srctest) {\n const dataSrc = iframeLoad.getAttribute(\"data-src\");\n if (dataSrc) {\n iframeLoad.setAttribute(\"src\", dataSrc);\n }\n }\n});\n\nlisten(\"click\", \"#copy_url\", async function (this: HTMLElement) {\n const target = this.parentElement?.querySelector<HTMLPreElement>(\"pre\");\n assertElement(target);\n\n await navigator.clipboard.writeText(target.innerText);\n const copiedText = this.dataset.copiedText;\n if (copiedText) {\n this.innerText = copiedText;\n }\n});\n\nlisten(\"click\", \".result-detail-close\", (event: Event) => {\n event.preventDefault();\n mutable.closeDetail?.();\n});\n\nlisten(\"click\", \".result-detail-previous\", (event: Event) => {\n event.preventDefault();\n mutable.selectPrevious?.(false);\n});\n\nlisten(\"click\", \".result-detail-next\", (event: Event) => {\n event.preventDefault();\n mutable.selectNext?.(false);\n});\n\n// listen for the back button to be pressed and dismiss the image details when called\nwindow.addEventListener(\"hashchange\", () => {\n if (window.location.hash !== \"#image-viewer\") {\n mutable.closeDetail?.();\n }\n});\n\nconst swipeHorizontal: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>(\".swipe-horizontal\");\nfor (const element of swipeHorizontal) {\n listen(\"swiped-left\", element, () => {\n mutable.selectNext?.(false);\n });\n\n listen(\"swiped-right\", element, () => {\n mutable.selectPrevious?.(false);\n });\n}\n\nwindow.addEventListener(\n \"scroll\",\n () => {\n const backToTopElement = document.getElementById(\"backToTop\");\n const resultsElement = document.getElementById(\"results\");\n\n if (backToTopElement && resultsElement) {\n const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n const isScrolling = scrollTop >= 100;\n resultsElement.classList.toggle(\"scrolling\", isScrolling);\n }\n },\n true\n);\n"],"x_google_ignoreList":[0],"mappings":"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"}
|