|
1 | 1 | import { Link, Publication } from "@readium/shared"; |
2 | | -import { webPubStylesheet } from "./css/WebPubStylesheet"; |
3 | 2 |
|
4 | | -// Utilities (matching FrameBlobBuilder pattern) |
| 3 | +// Readium CSS imports |
| 4 | +// The "?inline" query is to prevent some bundlers from injecting these into the page (e.g. vite) |
| 5 | +// @ts-ignore |
| 6 | +import readiumCSSWebPub from "@readium/css/css/dist/webPub/ReadiumCSS-webPub.css?inline"; |
| 7 | + |
| 8 | +// Utilities |
5 | 9 | const blobify = (source: string, type: string) => URL.createObjectURL(new Blob([source], { type })); |
6 | 10 | const stripJS = (source: string) => source.replace(/\/\/.*/g, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\n/g, "").replace(/\s+/g, " "); |
| 11 | +const stripCSS = (source: string) => source.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\/|[\r\n\t]+/g, '').replace(/ {2,}/g, ' ') |
| 12 | + // Fully resolve absolute local URLs created by bundlers since it's going into a blob |
| 13 | + .replace(/url\((?!(https?:)?\/\/)("?)\/([^\)]+)/g, `url($2${window.location.origin}/$3`); |
7 | 14 | const scriptify = (doc: Document, source: string) => { |
8 | 15 | const s = doc.createElement("script"); |
9 | 16 | s.dataset.readium = "true"; |
10 | 17 | s.src = source.startsWith("blob:") ? source : blobify(source, "text/javascript"); |
11 | 18 | return s; |
12 | 19 | } |
13 | 20 | const styleify = (doc: Document, source: string) => { |
14 | | - const s = doc.createElement("style"); |
| 21 | + const s = doc.createElement("link"); |
15 | 22 | s.dataset.readium = "true"; |
16 | | - s.textContent = source; |
| 23 | + s.rel = "stylesheet"; |
| 24 | + s.type = "text/css"; |
| 25 | + s.href = source.startsWith("blob:") ? source : blobify(source, "text/css"); |
17 | 26 | return s; |
18 | 27 | } |
19 | 28 |
|
20 | 29 | type CacheFunction = () => string; |
21 | 30 | const resourceBlobCache = new Map<string, string>(); |
22 | 31 | const cached = (key: string, cacher: CacheFunction) => { |
23 | | - if (resourceBlobCache.has(key)) return resourceBlobCache.get(key)!; |
| 32 | + if(resourceBlobCache.has(key)) return resourceBlobCache.get(key)!; |
24 | 33 | const value = cacher(); |
25 | 34 | resourceBlobCache.set(key, value); |
26 | 35 | return value; |
@@ -103,9 +112,9 @@ export class WebPubBlobBuilder { |
103 | 112 | private finalizeDOM(doc: Document, base: string | undefined, mediaType: any, txt?: string, cssProperties?: { [key: string]: string }): string { |
104 | 113 | if(!doc) return ""; |
105 | 114 |
|
106 | | - // Add WebPubCSS stylesheet at end of head (like EPUB ReadiumCSS-after) |
107 | | - const webPubStyle = styleify(doc, webPubStylesheet); |
108 | | - doc.head.appendChild(webPubStyle); |
| 115 | + // ReadiumCSS WebPub |
| 116 | + doc.head.appendChild(styleify(doc, cached("ReadiumCSS-webpub", () => blobify(stripCSS(readiumCSSWebPub), "text/css")))); |
| 117 | + |
109 | 118 | if (cssProperties) { |
110 | 119 | this.setProperties(cssProperties, doc); |
111 | 120 | } |
|
0 commit comments