mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-04 05:17:24 +02:00
Find the PDF filename in a URL hash in two linear steps
Searching for a name followed by ".pdf" is quadratic on a hash which doesn't contain one, so locate the last ".pdf" first and then extend it to the left.
This commit is contained in:
parent
7fc7072f9c
commit
7862875438
@ -188,10 +188,22 @@ function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") {
|
||||
}
|
||||
|
||||
if (newURL.hash) {
|
||||
const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
|
||||
const hashFilename = reFilename.exec(newURL.hash);
|
||||
if (hashFilename) {
|
||||
return decode(hashFilename[0]);
|
||||
// Locate the last ".pdf" and then extend it to the left, up to the closest
|
||||
// separator. Both steps are linear, whereas a single pattern starting with
|
||||
// `[^/?#=]+` is quadratic on a hash which contains no ".pdf" at all.
|
||||
const { hash } = newURL;
|
||||
let extensionStart = -1;
|
||||
for (const { index } of hash.matchAll(/\.pdf\b/gi)) {
|
||||
extensionStart = index;
|
||||
}
|
||||
if (extensionStart > 0) {
|
||||
let filenameStart = extensionStart;
|
||||
while (filenameStart > 0 && !"/?#=".includes(hash[filenameStart - 1])) {
|
||||
filenameStart--;
|
||||
}
|
||||
if (filenameStart < extensionStart) {
|
||||
return decode(hash.slice(filenameStart, extensionStart + 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +122,30 @@ describe("display_utils", function () {
|
||||
expect(
|
||||
getPdfFilenameFromUrl("http://www.example.com/pdfs/pdf.html#file2.pdf")
|
||||
).toEqual("file2.pdf");
|
||||
// Only the last ".pdf" of the hash is used.
|
||||
expect(getPdfFilenameFromUrl("/pdfs/pdfs.html#a.pdf/b.pdf")).toEqual(
|
||||
"b.pdf"
|
||||
);
|
||||
// A ".pdf" which isn't preceded by a name is ignored.
|
||||
expect(getPdfFilenameFromUrl("/pdfs/pdfs.html#=.pdf")).toEqual(
|
||||
"document.pdf"
|
||||
);
|
||||
// An invalid last ".pdf" prevents an earlier valid one from being used.
|
||||
expect(getPdfFilenameFromUrl("/pdfs/pdfs.html#a.pdf/=.pdf")).toEqual(
|
||||
"document.pdf"
|
||||
);
|
||||
});
|
||||
|
||||
it("gets PDF filename from a long hash string efficiently", function () {
|
||||
// Scanning the hash for a name is quadratic when it contains no ".pdf".
|
||||
const url = `/pdfs/pdfs.html#${"a".repeat(200000)}`;
|
||||
|
||||
const startTime = performance.now();
|
||||
const filename = getPdfFilenameFromUrl(url);
|
||||
const duration = performance.now() - startTime;
|
||||
|
||||
expect(filename).toEqual("document.pdf");
|
||||
expect(duration).toBeLessThan(1000);
|
||||
});
|
||||
|
||||
it("gets correct PDF filename when multiple ones are present", function () {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user