summaryrefslogtreecommitdiff
path: root/searx/static/themes/simple/chunk/DBO1tjH7.min.js.map
blob: abf75eca3285cf879c970b9690a01d8f85dceb02 (plain)
1
{"version":3,"file":"DBO1tjH7.min.js","names":[],"sources":["../../../../../client/simple/src/js/plugin/InfiniteScroll.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport { Plugin } from \"../Plugin.ts\";\nimport { http, settings } from \"../toolkit.ts\";\nimport { assertElement } from \"../util/assertElement.ts\";\nimport { getElement } from \"../util/getElement.ts\";\n\n/**\n * Automatically loads the next page when scrolling to bottom of the current page.\n */\nexport default class InfiniteScroll extends Plugin {\n  public constructor() {\n    super(\"infiniteScroll\");\n  }\n\n  protected async run(): Promise<void> {\n    const resultsElement = getElement<HTMLElement>(\"results\");\n\n    const onlyImages: boolean = resultsElement.classList.contains(\"only_template_images\");\n    const observedSelector = \"article.result:last-child\";\n\n    const spinnerElement = document.createElement(\"div\");\n    spinnerElement.className = \"loader\";\n\n    const loadNextPage = async (callback: () => void): Promise<void> => {\n      const searchForm = document.querySelector<HTMLFormElement>(\"#search\");\n      assertElement(searchForm);\n\n      const form = document.querySelector<HTMLFormElement>(\"#pagination form.next_page\");\n      assertElement(form);\n\n      const action = searchForm.getAttribute(\"action\");\n      if (!action) {\n        throw new Error(\"Form action not defined\");\n      }\n\n      const paginationElement = document.querySelector<HTMLElement>(\"#pagination\");\n      assertElement(paginationElement);\n\n      paginationElement.replaceChildren(spinnerElement);\n\n      try {\n        const res = await http(\"POST\", action, { body: new FormData(form) });\n        const nextPage = await res.text();\n        if (!nextPage) return;\n\n        const nextPageDoc = new DOMParser().parseFromString(nextPage, \"text/html\");\n        const articleList = nextPageDoc.querySelectorAll<HTMLElement>(\"#urls article\");\n        const nextPaginationElement = nextPageDoc.querySelector<HTMLElement>(\"#pagination\");\n\n        document.querySelector(\"#pagination\")?.remove();\n\n        const urlsElement = document.querySelector<HTMLElement>(\"#urls\");\n        if (!urlsElement) {\n          throw new Error(\"URLs element not found\");\n        }\n\n        if (articleList.length > 0 && !onlyImages) {\n          // do not add <hr> element when there are only images\n          urlsElement.appendChild(document.createElement(\"hr\"));\n        }\n\n        urlsElement.append(...articleList);\n\n        if (nextPaginationElement) {\n          const results = document.querySelector<HTMLElement>(\"#results\");\n          results?.appendChild(nextPaginationElement);\n          callback();\n        }\n      } catch (error) {\n        console.error(\"Error loading next page:\", error);\n\n        const errorElement = Object.assign(document.createElement(\"div\"), {\n          textContent: settings.translations?.error_loading_next_page ?? \"Error loading next page\",\n          className: \"dialog-error\"\n        });\n        errorElement.setAttribute(\"role\", \"alert\");\n        document.querySelector(\"#pagination\")?.replaceChildren(errorElement);\n      }\n    };\n\n    const intersectionObserveOptions: IntersectionObserverInit = {\n      rootMargin: \"320px\"\n    };\n\n    const observer: IntersectionObserver = new IntersectionObserver(async (entries: IntersectionObserverEntry[]) => {\n      const [paginationEntry] = entries;\n\n      if (paginationEntry?.isIntersecting) {\n        observer.unobserve(paginationEntry.target);\n\n        await loadNextPage(() => {\n          const nextObservedElement = document.querySelector<HTMLElement>(observedSelector);\n          if (nextObservedElement) {\n            observer.observe(nextObservedElement);\n          }\n        });\n      }\n    }, intersectionObserveOptions);\n\n    const initialObservedElement: HTMLElement | null = document.querySelector<HTMLElement>(observedSelector);\n    if (initialObservedElement) {\n      observer.observe(initialObservedElement);\n    }\n  }\n\n  protected async post(): Promise<void> {\n    // noop\n  }\n}\n"],"mappings":"kIAUA,IAAqB,EAArB,cAA4C,CAAO,CACjD,aAAqB,CACnB,MAAM,iBAAiB,CAGzB,MAAgB,KAAqB,CAGnC,IAAM,EAFiB,EAAwB,UAAU,CAEd,UAAU,SAAS,uBAAuB,CAC/E,EAAmB,4BAEnB,EAAiB,SAAS,cAAc,MAAM,CACpD,EAAe,UAAY,SAE3B,IAAM,EAAe,KAAO,IAAwC,CAClE,IAAM,EAAa,SAAS,cAA+B,UAAU,CACrE,EAAc,EAAW,CAEzB,IAAM,EAAO,SAAS,cAA+B,6BAA6B,CAClF,EAAc,EAAK,CAEnB,IAAM,EAAS,EAAW,aAAa,SAAS,CAChD,GAAI,CAAC,EACH,MAAU,MAAM,0BAA0B,CAG5C,IAAM,EAAoB,SAAS,cAA2B,cAAc,CAC5E,EAAc,EAAkB,CAEhC,EAAkB,gBAAgB,EAAe,CAEjD,GAAI,CAEF,IAAM,EAAW,MADL,MAAM,EAAK,OAAQ,EAAQ,CAAE,KAAM,IAAI,SAAS,EAAK,CAAE,CAAC,EACzC,MAAM,CACjC,GAAI,CAAC,EAAU,OAEf,IAAM,EAAc,IAAI,WAAW,CAAC,gBAAgB,EAAU,YAAY,CACpE,EAAc,EAAY,iBAA8B,gBAAgB,CACxE,EAAwB,EAAY,cAA2B,cAAc,CAEnF,SAAS,cAAc,cAAc,EAAE,QAAQ,CAE/C,IAAM,EAAc,SAAS,cAA2B,QAAQ,CAChE,GAAI,CAAC,EACH,MAAU,MAAM,yBAAyB,CAGvC,EAAY,OAAS,GAAK,CAAC,GAE7B,EAAY,YAAY,SAAS,cAAc,KAAK,CAAC,CAGvD,EAAY,OAAO,GAAG,EAAY,CAE9B,IACc,SAAS,cAA2B,WAAW,EACtD,YAAY,EAAsB,CAC3C,GAAU,QAEL,EAAO,CACd,QAAQ,MAAM,2BAA4B,EAAM,CAEhD,IAAM,EAAe,OAAO,OAAO,SAAS,cAAc,MAAM,CAAE,CAChE,YAAa,EAAS,cAAc,yBAA2B,0BAC/D,UAAW,eACZ,CAAC,CACF,EAAa,aAAa,OAAQ,QAAQ,CAC1C,SAAS,cAAc,cAAc,EAAE,gBAAgB,EAAa,GAQlE,EAAiC,IAAI,qBAAqB,KAAO,IAAyC,CAC9G,GAAM,CAAC,GAAmB,EAEtB,GAAiB,iBACnB,EAAS,UAAU,EAAgB,OAAO,CAE1C,MAAM,MAAmB,CACvB,IAAM,EAAsB,SAAS,cAA2B,EAAiB,CAC7E,GACF,EAAS,QAAQ,EAAoB,EAEvC,GAfuD,CAC3D,WAAY,QACb,CAe6B,CAExB,EAA6C,SAAS,cAA2B,EAAiB,CACpG,GACF,EAAS,QAAQ,EAAuB,CAI5C,MAAgB,MAAsB"}