Ship file viewer, editor improvements, and private package releases
This commit is contained in:
1 parent
645914955c
commit
a4a31032b9
158 files changed
+10523
-137
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import { setButtonLabel } from "./renderers/dom.ts";
|
||||
import { convertUrl, converterFormats } from "./convert/client.ts";
|
||||
import { extensionOf } from "./kinds.ts";
|
||||
import { readBounded } from "./source.ts";
|
||||
import type { ViewerSource } from "./types.ts";
|
||||
|
||||
/** Bounded plain text for search/indexing consumers; the server rechecks source access. */
|
||||
export async function extractText(
|
||||
source: ViewerSource,
|
||||
options: { baseURI?: string; signal?: AbortSignal; fetch?: typeof fetch } = {},
|
||||
): Promise<string> {
|
||||
const url = convertUrl(source, "text", options.baseURI);
|
||||
if (!url) throw new Error("Text extraction needs a URL");
|
||||
const response = await (options.fetch ?? fetch)(url, { signal: options.signal });
|
||||
if (!response.headers.get("content-type")?.startsWith("text/plain")) {
|
||||
await response.body?.cancel();
|
||||
throw new Error("Text extraction unavailable");
|
||||
}
|
||||
return new TextDecoder().decode(await readBounded(response, 2 * 1024 * 1024));
|
||||
}
|
||||
|
||||
export function mountExtractedText(
|
||||
parent: HTMLElement,
|
||||
source: ViewerSource,
|
||||
signal: AbortSignal,
|
||||
): () => void {
|
||||
const doc = parent.ownerDocument;
|
||||
const button = doc.createElement("button");
|
||||
button.type = "button";
|
||||
button.className = "wrn-viewer-action";
|
||||
setButtonLabel(button, "Extract text");
|
||||
const details = doc.createElement("details");
|
||||
const summary = doc.createElement("summary");
|
||||
summary.textContent = "Extracted text";
|
||||
const text = doc.createElement("pre");
|
||||
details.append(summary, text);
|
||||
let disposed = false;
|
||||
void converterFormats({ baseURI: doc.baseURI })
|
||||
.then((formats) => {
|
||||
if (!disposed && source.src && formats[extensionOf(source.name)]) parent.append(button);
|
||||
})
|
||||
.catch(() => {});
|
||||
button.onclick = async () => {
|
||||
button.disabled = true;
|
||||
try {
|
||||
const result = await extractText(source, { baseURI: doc.baseURI, signal });
|
||||
if (disposed) return;
|
||||
text.textContent = result || "No text was found.";
|
||||
details.open = true;
|
||||
parent.append(details);
|
||||
} catch {
|
||||
if (!disposed) {
|
||||
text.textContent = "Text extraction is unavailable.";
|
||||
details.open = true;
|
||||
parent.append(details);
|
||||
}
|
||||
} finally {
|
||||
if (!disposed) button.disabled = false;
|
||||
}
|
||||
};
|
||||
return () => {
|
||||
disposed = true;
|
||||
button.remove();
|
||||
details.remove();
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user