diff --git a/src/classes/Chapter.ts b/src/classes/Chapter.ts index bfa4116..ae6d53c 100644 --- a/src/classes/Chapter.ts +++ b/src/classes/Chapter.ts @@ -118,15 +118,15 @@ export default class Chapter { async populateText() { this.#text = ""; - Array.from( - this.#document.querySelectorAll( - "div.userstuff[role='article'] > p", - ), - ).forEach( - (t) => { - this.#text += (t as Element).innerText + "\n"; - }, + const elements = this.#document.querySelectorAll( + "div.userstuff[role='article'] > p", ); + + for (let i = 0; i < elements.length; i++) { + const element = elements[i] as Element; + + this.#text += element.innerText + "\n"; + } try { this.#text = this.#text.trim(); @@ -147,16 +147,16 @@ export default class Chapter { "[role='article'] > div.userstuff", ) as Element).innerHTML; - Array.from( - this.#document.querySelectorAll( - "[role='article'] > div.userstuff > p", - ), - ).forEach( - (t) => { - this.#text += (t as Element).innerText + "\n"; - this.#html += (t as Element).innerHTML; - }, + const elements = this.#document.querySelectorAll( + "[role='article'] > div.userstuff > p", ); + + for (let i = 0; i < elements.length; i++) { + const element = elements[i] as Element; + + this.#text += element.innerText + "\n"; + this.#html += element.innerHTML; + } } } } diff --git a/src/classes/Search.ts b/src/classes/Search.ts index 623b72d..e47d001 100644 --- a/src/classes/Search.ts +++ b/src/classes/Search.ts @@ -1,7 +1,6 @@ //NOTE: AO3's searching "api" is an absolute clusterfuck. i'm sorry. import Work from "./Work.ts"; -import asyncForEach from "../utils/asyncForeach.ts"; import { DOMParser, Element, HTMLDocument } from "../types.d.ts"; export const Ratings = { @@ -102,29 +101,29 @@ export default class Search { "text/html", ) as HTMLDocument; - let i = 0; const limit = this.#opts.limit ?? 20; - await asyncForEach( - Array.from(this.#document.querySelectorAll("[role='article']")), - async (e: Element) => { - if (i >= limit) { - return; - } - const workId = e.id.replace("work_", ""); - //console.log(workId); - const res = await this.#session.get( - `/works/${workId}?view_adult=true&view_full_work=true`, - ); - const work = new Work( - workId, - await res.text(), - this.#session, - this.#DOMParser, - ); - await work.init(); - this.results.push(work); - i++; - }, - ); + const elements = this.#document.querySelectorAll("[role='article']"); + + for (let i = 0; i < elements.length; i++) { + const element: Element = elements[i] as Element; + + if (i >= limit) { + return; + } + + const workId = element.id.replace("work_", ""); + const res = await this.#session.get( + `/works/${workId}?view_adult=true&view_full_work=true`, + ); + const work = new Work( + workId, + await res.text(), + this.#session, + this.#DOMParser, + ); + + await work.init(); + this.results.push(work); + } } } diff --git a/src/classes/Work.ts b/src/classes/Work.ts index 6cfdc7c..e881745 100644 --- a/src/classes/Work.ts +++ b/src/classes/Work.ts @@ -75,34 +75,24 @@ export default class Work { } populateTags() { - Array.from( - (this.#document.querySelector("dd.fandom > ul.commas") as Element) - ?.children ?? [], - ).map( - (t) => this.tags.push(t.children[0].innerText), + /* this.#document.querySelectorAll("dd.fandom > ul.commas > li").map( + (t) => this.tags.push(t.text), ); - Array.from( - (this.#document.querySelector( - "dd.relationship > ul.commas", - ) as Element) - ?.children ?? [], - ).map( - (t) => this.tags.push(t.children[0].innerText), + this.#document.querySelectorAll("dd.relationship > ul.commas > li").map( + (t) => this.tags.push(t.text), ); - Array.from( - (this.#document.querySelector( - "dd.character > ul.commas", - ) as Element) - ?.children ?? [], - ).map( - (t) => this.tags.push(t.children[0].innerText), - ); - Array.from( - (this.#document.querySelector("dd.freeform > ul.commas") as Element) - ?.children ?? [], //does that make me insane - ).map( - (t) => this.tags.push(t.children[0].innerText), + this.#document.querySelectorAll("dd.character > ul.commas > li").map( + (t) => this.tags.push(t.text), ); + this.#document.querySelectorAll("dd.freeform > ul.commas > li").map( + (t) => this.tags.push(t.text), + ); */ + + const elements = this.#document.querySelectorAll("dd > ul.commas > li"); + + for (let i = 0; i < elements.length; i++) { + this.tags.push((elements[i] as Element)?.innerText); + } } populateDates() { @@ -143,23 +133,29 @@ export default class Work { "text/html", ) as HTMLDocument; - Array.from((document.getElementById("selected_id") as Element).children) + const elements = (Array.from( + document.querySelectorAll("#selected_id > option"), + ) as Element[]) .sort( - (a, b) => { + (a: Element, b: Element) => { return Number(a.getAttribute("value")) - Number(b.getAttribute("value")); }, - ).forEach((c) => { - const newChapter = new Chapter( - this.id, - c.getAttribute("value") as string, - this.#session, - this.#DOMParser, - { name: c.innerText }, - ); - this.chapters.push( - newChapter, - ); - }); + ); + + for (let i = 0; i < elements.length; i++) { + const element = elements[i]; + + const newChapter = new Chapter( + this.id, + element.getAttribute("value") as string, + this.#session, + this.#DOMParser, + { name: element.innerText }, + ); + this.chapters.push( + newChapter, + ); + } } } diff --git a/src/utils/asyncForeach.ts b/src/utils/asyncForeach.ts deleted file mode 100644 index 782b62c..0000000 --- a/src/utils/asyncForeach.ts +++ /dev/null @@ -1,9 +0,0 @@ -// deno-lint-ignore-file no-explicit-any -export default async function asyncForEach( - array: any[], - callback: (val: any, index: number, array: any[]) => Promise, -) { - for (let index = 0; index < array.length; index++) { - await callback(array[index], index, array); - } -} diff --git a/tests/index.ts b/tests/index.ts index 79eaea6..0220179 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -1,8 +1,10 @@ import AO3 from "../src/classes/AO3.ts"; import workTest from "./work.ts"; import chaptersTest from "./chapter.ts"; +import searchTest from "./search.ts"; const ao3 = new AO3(); await workTest(ao3); await chaptersTest(ao3); +await searchTest(ao3); diff --git a/tests/search.ts b/tests/search.ts index e69de29..c81fa00 100644 --- a/tests/search.ts +++ b/tests/search.ts @@ -0,0 +1,35 @@ +import AO3 from "../mod.ts"; +import type { Search } from "../mod.ts"; +import { assert } from "https://deno.land/std@0.167.0/testing/asserts.ts"; + +export default function test(ao3: AO3) { + Deno.test("searches", async (test) => { + await test.step("specific search", async () => { + const search = ao3.search({ + freeform: [ + "no beta we die like sammy", + "not at all your honor", + ], + fandoms: ["Bendy and the Ink Machine"], + }); + await search.update(0); + + assert(search.results[0].id === "43251729", "incorrect work found"); + }); + await test.step("broad search", async () => { + const search = ao3.search({ + freeform: [ + "Smut", + ], + }); + await search.update(0); + assert(search.results.length > 10, "not enough search results"); + + await search.update(1); + assert( + search.results.length > 10, + "could not find second page of results", + ); + }); + }); +}